You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by rx...@apache.org on 2020/08/05 10:44:18 UTC
[pulsar] 07/07: Add window context function example
This is an automated email from the ASF dual-hosted git repository.
rxl pushed a commit to branch branch-2.6
in repository https://gitbox.apache.org/repos/asf/pulsar.git
commit 8b4a92186b45f3109012e32b5aea3b46b264f252
Author: 冉小龙 <rx...@apache.org>
AuthorDate: Wed Aug 5 11:12:24 2020 +0800
Add window context function example
Signed-off-by: xiaolong.ran <rx...@apache.org>
---
site2/docs/window-functions-context.md | 528 ++++++++++++++++++++
site2/website/sidebars.json | 3 +-
.../version-2.3.0/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.3.1/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.3.2/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.4.0/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.4.1/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.4.2/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.5.0/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.5.1/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.5.2/window-functions-context.md | 529 +++++++++++++++++++++
.../version-2.6.0/window-functions-context.md | 529 +++++++++++++++++++++
.../versioned_sidebars/version-2.3.0-sidebars.json | 3 +-
.../versioned_sidebars/version-2.3.1-sidebars.json | 3 +-
.../versioned_sidebars/version-2.3.2-sidebars.json | 3 +-
.../versioned_sidebars/version-2.4.0-sidebars.json | 3 +-
.../versioned_sidebars/version-2.4.1-sidebars.json | 3 +-
.../versioned_sidebars/version-2.4.2-sidebars.json | 3 +-
.../versioned_sidebars/version-2.5.0-sidebars.json | 3 +-
.../versioned_sidebars/version-2.5.1-sidebars.json | 3 +-
.../versioned_sidebars/version-2.5.2-sidebars.json | 3 +-
.../versioned_sidebars/version-2.6.0-sidebars.json | 153 ++++++
22 files changed, 5991 insertions(+), 10 deletions(-)
diff --git a/site2/docs/window-functions-context.md b/site2/docs/window-functions-context.md
new file mode 100644
index 0000000..e81f6e8
--- /dev/null
+++ b/site2/docs/window-functions-context.md
@@ -0,0 +1,528 @@
+---
+id: window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/sidebars.json b/site2/website/sidebars.json
index 480e276..a402a13 100644
--- a/site2/website/sidebars.json
+++ b/site2/website/sidebars.json
@@ -32,7 +32,8 @@
"functions-develop",
"functions-debug",
"functions-deploy",
- "functions-cli"
+ "functions-cli",
+ "window-functions-context"
],
"Pulsar IO": [
"io-overview",
diff --git a/site2/website/versioned_docs/version-2.3.0/window-functions-context.md b/site2/website/versioned_docs/version-2.3.0/window-functions-context.md
new file mode 100644
index 0000000..752f95a
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.3.0/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.3.0-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.3.1/window-functions-context.md b/site2/website/versioned_docs/version-2.3.1/window-functions-context.md
new file mode 100644
index 0000000..94280f6
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.3.1/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.3.1-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.3.2/window-functions-context.md b/site2/website/versioned_docs/version-2.3.2/window-functions-context.md
new file mode 100644
index 0000000..0a4ae0e
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.3.2/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.3.2-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.4.0/window-functions-context.md b/site2/website/versioned_docs/version-2.4.0/window-functions-context.md
new file mode 100644
index 0000000..f1a72e0
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.4.0/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.4.0-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.4.1/window-functions-context.md b/site2/website/versioned_docs/version-2.4.1/window-functions-context.md
new file mode 100644
index 0000000..e0b0e36
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.4.1/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.4.1-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.4.2/window-functions-context.md b/site2/website/versioned_docs/version-2.4.2/window-functions-context.md
new file mode 100644
index 0000000..1faa230
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.4.2/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.4.2-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.5.0/window-functions-context.md b/site2/website/versioned_docs/version-2.5.0/window-functions-context.md
new file mode 100644
index 0000000..d9dfd21
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.5.0/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.5.0-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.5.1/window-functions-context.md b/site2/website/versioned_docs/version-2.5.1/window-functions-context.md
new file mode 100644
index 0000000..2541cb1
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.5.1/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.5.1-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.5.2/window-functions-context.md b/site2/website/versioned_docs/version-2.5.2/window-functions-context.md
new file mode 100644
index 0000000..b51add3
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.5.2/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.5.2-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_docs/version-2.6.0/window-functions-context.md b/site2/website/versioned_docs/version-2.6.0/window-functions-context.md
new file mode 100644
index 0000000..f4216b9
--- /dev/null
+++ b/site2/website/versioned_docs/version-2.6.0/window-functions-context.md
@@ -0,0 +1,529 @@
+---
+id: version-2.6.0-window-functions-context
+title: Window Functions Context
+sidebar_label: "Window Functions: Context"
+original_id: window-functions-context
+---
+
+Java SDK provides access to a **window context object** that can be used by a window function. This context object provides a wide variety of information and functionality for Pulsar window functions as below.
+
+- [Spec](#spec)
+
+ * Names of all input topics and the output topic associated with the function.
+ * Tenant and namespace associated with the function.
+ * Pulsar window function name, ID, and version.
+ * ID of the Pulsar function instance running the window function.
+ * Number of instances that invoke the window function.
+ * Built-in type or custom class name of the output schema.
+
+- [Logger](#logger)
+
+ * Logger object used by the window function, which can be used to create window function log messages.
+
+- [User config](#user-config)
+
+ * Access to arbitrary user configuration values.
+
+- [Routing](#routing)
+
+ * Routing is supported in Pulsar window functions. Pulsar window functions send messages to arbitrary topics as per the `publish` interface.
+
+- [Metrics](#metrics)
+
+ * Interface for recording metrics.
+
+- [State storage](#state-storage)
+
+ * Interface for storing and retrieving state in [state storage](#state-storage).
+
+## Spec
+
+Spec contains the basic information of a function.
+
+### Get input topics
+
+The `getInputTopics` method gets the **name list** of all input topics.
+
+This example demonstrates how to get the name list of all input topics in a Java window function.
+
+```java
+public class GetInputTopicsWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Collection<String> inputTopics = context.getInputTopics();
+ System.out.println(inputTopics);
+
+ return null;
+ }
+
+}
+```
+
+### Get output topic
+
+The `getOutputTopic` method gets the **name of a topic** to which the message is sent.
+
+This example demonstrates how to get the name of an output topic in a Java window function.
+
+```java
+public class GetOutputTopicWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String outputTopic = context.getOutputTopic();
+ System.out.println(outputTopic);
+
+ return null;
+ }
+}
+```
+
+### Get tenant
+
+The `getTenant` method gets the tenant name associated with the window function.
+
+This example demonstrates how to get the tenant name in a Java window function.
+
+```java
+public class GetTenantWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String tenant = context.getTenant();
+ System.out.println(tenant);
+
+ return null;
+ }
+
+}
+```
+
+### Get namespace
+
+The `getNamespace` method gets the namespace associated with the window function.
+
+This example demonstrates how to get the namespace in a Java window function.
+
+```java
+public class GetNamespaceWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String ns = context.getNamespace();
+ System.out.println(ns);
+
+ return null;
+ }
+
+}
+```
+
+### Get function name
+
+The `getFunctionName` method gets the window function name.
+
+This example demonstrates how to get the function name in a Java window function.
+
+```java
+public class GetNameOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionName = context.getFunctionName();
+ System.out.println(functionName);
+
+ return null;
+ }
+
+}
+```
+
+### Get function ID
+
+The `getFunctionId` method gets the window function ID.
+
+This example demonstrates how to get the function ID in a Java window function.
+
+```java
+public class GetFunctionIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionID = context.getFunctionId();
+ System.out.println(functionID);
+
+ return null;
+ }
+
+}
+```
+
+### Get function version
+
+The `getFunctionVersion` method gets the window function version.
+
+This example demonstrates how to get the function version of a Java window function.
+
+```java
+public class GetVersionOfWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String functionVersion = context.getFunctionVersion();
+ System.out.println(functionVersion);
+
+ return null;
+ }
+
+}
+```
+
+### Get instance ID
+
+The `getInstanceId` method gets the instance ID of a window function.
+
+This example demonstrates how to get the instance ID in a Java window function.
+
+```java
+public class GetInstanceIDWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int instanceId = context.getInstanceId();
+ System.out.println(instanceId);
+
+ return null;
+ }
+
+}
+```
+
+### Get num instances
+
+The `getNumInstances` method gets the number of instances that invoke the window function.
+
+This example demonstrates how to get the number of instances in a Java window function.
+
+```java
+public class GetNumInstancesWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ int numInstances = context.getNumInstances();
+ System.out.println(numInstances);
+
+ return null;
+ }
+
+}
+```
+
+### Get output schema type
+
+The `getOutputSchemaType` method gets the built-in type or custom class name of the output schema.
+
+This example demonstrates how to get the output schema type of a Java window function.
+
+```java
+public class GetOutputSchemaTypeWindowFunction implements WindowFunction<String, Void> {
+
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ String schemaType = context.getOutputSchemaType();
+ System.out.println(schemaType);
+
+ return null;
+ }
+}
+```
+
+## Logger
+
+Pulsar window functions using Java SDK has access to an [SLF4j](https://www.slf4j.org/) [`Logger`](https://www.slf4j.org/api/org/apache/log4j/Logger.html) object that can be used to produce logs at the chosen log level.
+
+This example logs either a `WARNING`-level or `INFO`-level log based on whether the incoming string contains the word `danger` or not in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+import org.slf4j.Logger;
+
+public class LoggingWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ Logger log = context.getLogger();
+ for (Record<String> record : inputs) {
+ log.info(record + "-window-log");
+ }
+ return null;
+ }
+
+}
+```
+
+If you need your function to produce logs, specify a log topic when creating or running the function.
+
+```bash
+bin/pulsar-admin functions create \
+ --jar my-functions.jar \
+ --classname my.package.LoggingFunction \
+ --log-topic persistent://public/default/logging-function-logs \
+ # Other function configs
+```
+
+You can access all logs produced by `LoggingFunction` via the `persistent://public/default/logging-function-logs` topic.
+
+## Metrics
+
+Pulsar window functions can publish arbitrary metrics to the metrics interface which can be queried.
+
+> **Note**
+>
+> If a Pulsar window function uses the language-native interface for Java, that function is not able to publish metrics and stats to Pulsar.
+
+You can record metrics using the context object on a per-key basis.
+
+This example sets a metric for the `process-count` key and a different metric for the `elevens-count` key every time the function processes a message in a Java function.
+
+```java
+import java.util.Collection;
+import org.apache.pulsar.functions.api.Record;
+import org.apache.pulsar.functions.api.WindowContext;
+import org.apache.pulsar.functions.api.WindowFunction;
+
+
+/**
+ * Example function that wants to keep track of
+ * the event time of each message sent.
+ */
+public class UserMetricWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+
+ for (Record<String> record : inputs) {
+ if (record.getEventTime().isPresent()) {
+ context.recordMetric("MessageEventTime", record.getEventTime().get().doubleValue());
+ }
+ }
+
+ return null;
+ }
+}
+```
+
+## User config
+
+When you run or update Pulsar Functions that are created using SDK, you can pass arbitrary key/value pairs to them with the `--user-config` flag. Key/value pairs **must** be specified as JSON.
+
+This example passes a user configured key/value to a function.
+
+```bash
+bin/pulsar-admin functions create \
+ --name word-filter \
+ --user-config '{"forbidden-word":"rosebud"}' \
+ # Other function configs
+```
+
+### API
+You can use the following APIs to get user-defined information for window functions.
+#### getUserConfigMap
+
+`getUserConfigMap` API gets a map of all user-defined key/value configurations for the window function.
+
+
+```java
+/**
+ * Get a map of all user-defined key/value configs for the function.
+ *
+ * @return The full map of user-defined config values
+ */
+ Map<String, Object> getUserConfigMap();
+```
+
+
+#### getUserConfigValue
+
+The `getUserConfigValue` API gets a user-defined key/value.
+
+```java
+/**
+ * Get any user-defined key/value.
+ *
+ * @param key The key
+ * @return The Optional value specified by the user for that key.
+ */
+ Optional<Object> getUserConfigValue(String key);
+```
+
+#### getUserConfigValueOrDefault
+
+The `getUserConfigValueOrDefault` API gets a user-defined key/value or a default value if none is present.
+
+```java
+/**
+ * Get any user-defined key/value or a default value if none is present.
+ *
+ * @param key
+ * @param defaultValue
+ * @return Either the user config value associated with a given key or a supplied default value
+ */
+ Object getUserConfigValueOrDefault(String key, Object defaultValue);
+```
+
+This example demonstrates how to access key/value pairs provided to Pulsar window functions.
+
+Java SDK context object enables you to access key/value pairs provided to Pulsar window functions via the command line (as JSON).
+
+>**Tip**
+>
+> For all key/value pairs passed to Java window functions, both the `key` and the `value` are `String`. To set the value to be a different type, you need to deserialize it from the `String` type.
+
+This example passes a key/value pair in a Java window function.
+
+```bash
+bin/pulsar-admin functions create \
+ --user-config '{"word-of-the-day":"verdure"}' \
+ # Other function configs
+ ```
+
+This example accesses values in a Java window function.
+
+The `UserConfigFunction` function logs the string `"The word of the day is verdure"` every time the function is invoked (which means every time a message arrives). The user config of `word-of-the-day` is changed **only** when the function is updated with a new config value via
+multiple ways, such as the command line tool or REST API.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+import org.slf4j.Logger;
+
+import java.util.Optional;
+
+public class UserConfigWindowFunction implements WindowFunction<String, String> {
+ @Override
+ public String process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ Optional<Object> whatToWrite = context.getUserConfigValue("WhatToWrite");
+ if (whatToWrite.get() != null) {
+ return (String)whatToWrite.get();
+ } else {
+ return "Not a nice way";
+ }
+ }
+
+}
+```
+
+If no value is provided, you can access the entire user config map or set a default value.
+
+```java
+// Get the whole config map
+Map<String, String> allConfigs = context.getUserConfigMap();
+
+// Get value or resort to default
+String wotd = context.getUserConfigValueOrDefault("word-of-the-day", "perspicacious");
+```
+
+## Routing
+
+You can use the `context.publish()` interface to publish as many results as you want.
+
+This example shows that the `PublishFunction` class uses the built-in function in the context to publish messages to the `publishTopic` in a Java function.
+
+```java
+public class PublishWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> input, WindowContext context) throws Exception {
+ String publishTopic = (String) context.getUserConfigValueOrDefault("publish-topic", "publishtopic");
+ String output = String.format("%s!", input);
+ context.publish(publishTopic, output);
+
+ return null;
+ }
+
+}
+```
+
+## State storage
+
+Pulsar window functions use [Apache BookKeeper](https://bookkeeper.apache.org) as a state storage interface. Apache Pulsar installation (including the standalone installation) includes the deployment of BookKeeper bookies.
+
+Apache Pulsar integrates with Apache BookKeeper `table service` to store the `state` for functions. For example, the `WordCount` function can store its `counters` state into BookKeeper table service via Pulsar Functions state APIs.
+
+States are key-value pairs, where the key is a string and the value is arbitrary binary data—counters are stored as 64-bit big-endian binary values. Keys are scoped to an individual Pulsar Function and shared between instances of that function.
+
+Currently, Pulsar window functions expose Java API to access, update, and manage states. These APIs are available in the context object when you use Java SDK functions.
+
+| Java API| Description
+|---|---
+|`incrCounter`|Increases a built-in distributed counter referred by key.
+|`getCounter`|Gets the counter value for the key.
+|`putState`|Updates the state value for the key.
+
+You can use the following APIs to access, update, and manage states in Java window functions.
+
+#### incrCounter
+
+The `incrCounter` API increases a built-in distributed counter referred by key.
+
+Applications use the `incrCounter` API to change the counter of a given `key` by the given `amount`. If the `key` does not exist, a new key is created.
+
+```java
+ /**
+ * Increment the builtin distributed counter referred by key
+ * @param key The name of the key
+ * @param amount The amount to be incremented
+ */
+ void incrCounter(String key, long amount);
+```
+
+#### getCounter
+
+The `getCounter` API gets the counter value for the key.
+
+Applications uses the `getCounter` API to retrieve the counter of a given `key` changed by the `incrCounter` API.
+
+```java
+ /**
+ * Retrieve the counter value for the key.
+ *
+ * @param key name of the key
+ * @return the amount of the counter value for this key
+ */
+ long getCounter(String key);
+```
+
+Except the `getCounter` API, Pulsar also exposes a general key/value API (`putState`) for functions to store general key/value state.
+
+#### putState
+
+The `putState` API updates the state value for the key.
+
+```java
+ /**
+ * Update the state value for the key.
+ *
+ * @param key name of the key
+ * @param value state value of the key
+ */
+ void putState(String key, ByteBuffer value);
+```
+
+This example demonstrates how applications store states in Pulsar window functions.
+
+The logic of the `WordCountWindowFunction` is simple and straightforward.
+
+1. The function first splits the received string into multiple words using regex `\\.`.
+
+2. For each `word`, the function increments the corresponding `counter` by 1 via `incrCounter(key, amount)`.
+
+```java
+import org.apache.pulsar.functions.api.Context;
+import org.apache.pulsar.functions.api.Function;
+
+import java.util.Arrays;
+
+public class WordCountWindowFunction implements WindowFunction<String, Void> {
+ @Override
+ public Void process(Collection<Record<String>> inputs, WindowContext context) throws Exception {
+ for (Record<String> input : inputs) {
+ Arrays.asList(input.getValue().split("\\.")).forEach(word -> context.incrCounter(word, 1));
+ }
+ return null;
+
+ }
+}
+```
+
diff --git a/site2/website/versioned_sidebars/version-2.3.0-sidebars.json b/site2/website/versioned_sidebars/version-2.3.0-sidebars.json
index 5a66aad..4da977c 100644
--- a/site2/website/versioned_sidebars/version-2.3.0-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.3.0-sidebars.json
@@ -25,7 +25,8 @@
"version-2.3.0-functions-deploying",
"version-2.3.0-functions-guarantees",
"version-2.3.0-functions-state",
- "version-2.3.0-functions-metrics"
+ "version-2.3.0-functions-metrics",
+ "version-2.3.0-window-functions-context"
],
"Pulsar IO": [
"version-2.3.0-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.3.1-sidebars.json b/site2/website/versioned_sidebars/version-2.3.1-sidebars.json
index b732733..cd37319 100644
--- a/site2/website/versioned_sidebars/version-2.3.1-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.3.1-sidebars.json
@@ -25,7 +25,8 @@
"version-2.3.1-functions-deploying",
"version-2.3.1-functions-guarantees",
"version-2.3.1-functions-state",
- "version-2.3.1-functions-metrics"
+ "version-2.3.1-functions-metrics",
+ "version-2.3.1-window-functions-context"
],
"Pulsar IO": [
"version-2.3.1-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.3.2-sidebars.json b/site2/website/versioned_sidebars/version-2.3.2-sidebars.json
index f221ae3..16731e3 100644
--- a/site2/website/versioned_sidebars/version-2.3.2-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.3.2-sidebars.json
@@ -26,7 +26,8 @@
"version-2.3.2-functions-guarantees",
"version-2.3.2-functions-state",
"version-2.3.2-functions-metrics",
- "version-2.3.2-functions-worker"
+ "version-2.3.2-functions-worker",
+ "version-2.3.2-window-functions-context"
],
"Pulsar IO": [
"version-2.3.2-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.4.0-sidebars.json b/site2/website/versioned_sidebars/version-2.4.0-sidebars.json
index a6af729..93cef5a 100644
--- a/site2/website/versioned_sidebars/version-2.4.0-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.4.0-sidebars.json
@@ -28,7 +28,8 @@
"version-2.4.0-functions-metrics",
"version-2.4.0-functions-worker",
"version-2.4.0-functions-runtime",
- "version-2.4.0-functions-debugging"
+ "version-2.4.0-functions-debugging",
+ "version-2.4.0-window-functions-context"
],
"Pulsar IO": [
"version-2.4.0-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.4.1-sidebars.json b/site2/website/versioned_sidebars/version-2.4.1-sidebars.json
index c53d0fb..9fc7ff7 100644
--- a/site2/website/versioned_sidebars/version-2.4.1-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.4.1-sidebars.json
@@ -35,7 +35,8 @@
"version-2.4.1-functions-monitor",
"version-2.4.1-functions-secure",
"version-2.4.1-functions-troubleshoot",
- "version-2.4.1-functions-cli"
+ "version-2.4.1-functions-cli",
+ "version-2.4.1-window-functions-context"
],
"Pulsar IO": [
"version-2.4.1-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.4.2-sidebars.json b/site2/website/versioned_sidebars/version-2.4.2-sidebars.json
index e82a731..c119706 100644
--- a/site2/website/versioned_sidebars/version-2.4.2-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.4.2-sidebars.json
@@ -35,7 +35,8 @@
"version-2.4.2-functions-monitor",
"version-2.4.2-functions-secure",
"version-2.4.2-functions-troubleshoot",
- "version-2.4.2-functions-cli"
+ "version-2.4.2-functions-cli",
+ "version-2.4.2-window-functions-context"
],
"Pulsar IO": [
"version-2.4.2-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.5.0-sidebars.json b/site2/website/versioned_sidebars/version-2.5.0-sidebars.json
index 5270e22..dd98dc1 100644
--- a/site2/website/versioned_sidebars/version-2.5.0-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.5.0-sidebars.json
@@ -32,7 +32,8 @@
"version-2.5.0-functions-develop",
"version-2.5.0-functions-debug",
"version-2.5.0-functions-deploy",
- "version-2.5.0-functions-cli"
+ "version-2.5.0-functions-cli",
+ "version-2.5.0-window-functions-context"
],
"Pulsar IO": [
"version-2.5.0-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.5.1-sidebars.json b/site2/website/versioned_sidebars/version-2.5.1-sidebars.json
index e0348e1..64fbb99 100644
--- a/site2/website/versioned_sidebars/version-2.5.1-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.5.1-sidebars.json
@@ -31,7 +31,8 @@
"version-2.5.1-functions-develop",
"version-2.5.1-functions-debug",
"version-2.5.1-functions-deploy",
- "version-2.5.1-functions-cli"
+ "version-2.5.1-functions-cli",
+ "version-2.5.1-window-functions-context"
],
"Pulsar IO": [
"version-2.5.1-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.5.2-sidebars.json b/site2/website/versioned_sidebars/version-2.5.2-sidebars.json
index e97135e..c2456cc 100644
--- a/site2/website/versioned_sidebars/version-2.5.2-sidebars.json
+++ b/site2/website/versioned_sidebars/version-2.5.2-sidebars.json
@@ -31,7 +31,8 @@
"version-2.5.2-functions-develop",
"version-2.5.2-functions-debug",
"version-2.5.2-functions-deploy",
- "version-2.5.2-functions-cli"
+ "version-2.5.2-functions-cli",
+ "version-2.5.2-window-functions-context"
],
"Pulsar IO": [
"version-2.5.2-io-overview",
diff --git a/site2/website/versioned_sidebars/version-2.6.0-sidebars.json b/site2/website/versioned_sidebars/version-2.6.0-sidebars.json
new file mode 100644
index 0000000..6cd23e7
--- /dev/null
+++ b/site2/website/versioned_sidebars/version-2.6.0-sidebars.json
@@ -0,0 +1,153 @@
+{
+ "version-2.6.0-docs": {
+ "Get started": [
+ "version-2.6.0-pulsar-2.0",
+ "version-2.6.0-standalone",
+ "version-2.6.0-standalone-docker",
+ "version-2.6.0-kubernetes-helm",
+ "version-2.6.0-client-libraries"
+ ],
+ "Concepts and Architecture": [
+ "version-2.6.0-concepts-overview",
+ "version-2.6.0-concepts-messaging",
+ "version-2.6.0-concepts-architecture-overview",
+ "version-2.6.0-concepts-clients",
+ "version-2.6.0-concepts-replication",
+ "version-2.6.0-concepts-multi-tenancy",
+ "version-2.6.0-concepts-authentication",
+ "version-2.6.0-concepts-topic-compaction",
+ "version-2.6.0-concepts-tiered-storage"
+ ],
+ "Pulsar Schema": [
+ "version-2.6.0-schema-get-started",
+ "version-2.6.0-schema-understand",
+ "version-2.6.0-schema-evolution-compatibility",
+ "version-2.6.0-schema-manage"
+ ],
+ "Pulsar Functions": [
+ "version-2.6.0-functions-overview",
+ "version-2.6.0-functions-worker",
+ "version-2.6.0-functions-runtime",
+ "version-2.6.0-functions-develop",
+ "version-2.6.0-functions-debug",
+ "version-2.6.0-functions-deploy",
+ "version-2.6.0-functions-cli",
+ "version-2.6.0-window-functions-context"
+ ],
+ "Pulsar IO": [
+ "version-2.6.0-io-overview",
+ "version-2.6.0-io-quickstart",
+ "version-2.6.0-io-use",
+ "version-2.6.0-io-debug",
+ "version-2.6.0-io-connectors",
+ "version-2.6.0-io-cdc",
+ "version-2.6.0-io-develop",
+ "version-2.6.0-io-cli"
+ ],
+ "Pulsar SQL": [
+ "version-2.6.0-sql-overview",
+ "version-2.6.0-sql-getting-started",
+ "version-2.6.0-sql-deployment-configurations",
+ "version-2.6.0-sql-rest-api"
+ ],
+ "Kubernetes (Helm)": [
+ "version-2.6.0-helm-overview",
+ "version-2.6.0-helm-prepare",
+ "version-2.6.0-helm-install",
+ "version-2.6.0-helm-deploy",
+ "version-2.6.0-helm-upgrade",
+ "version-2.6.0-helm-tools"
+ ],
+ "Deployment": [
+ "version-2.6.0-deploy-aws",
+ "version-2.6.0-deploy-kubernetes",
+ "version-2.6.0-deploy-bare-metal",
+ "version-2.6.0-deploy-bare-metal-multi-cluster",
+ "version-2.6.0-deploy-dcos",
+ "version-2.6.0-deploy-monitoring"
+ ],
+ "Administration": [
+ "version-2.6.0-administration-zk-bk",
+ "version-2.6.0-administration-geo",
+ "version-2.6.0-administration-pulsar-manager",
+ "version-2.6.0-administration-stats",
+ "version-2.6.0-administration-load-balance",
+ "version-2.6.0-administration-proxy",
+ "version-2.6.0-administration-upgrade"
+ ],
+ "Security": [
+ "version-2.6.0-security-overview",
+ "version-2.6.0-security-tls-transport",
+ "version-2.6.0-security-tls-authentication",
+ "version-2.6.0-security-tls-keystore",
+ "version-2.6.0-security-jwt",
+ "version-2.6.0-security-athenz",
+ "version-2.6.0-security-kerberos",
+ "version-2.6.0-security-authorization",
+ "version-2.6.0-security-encryption",
+ "version-2.6.0-security-extending",
+ "version-2.6.0-security-bouncy-castle"
+ ],
+ "Performance": [
+ "version-2.6.0-performance-pulsar-perf"
+ ],
+ "Client libraries": [
+ "version-2.6.0-client-libraries-java",
+ "version-2.6.0-client-libraries-go",
+ "version-2.6.0-client-libraries-python",
+ "version-2.6.0-client-libraries-cpp",
+ "version-2.6.0-client-libraries-node",
+ "version-2.6.0-client-libraries-websocket",
+ "version-2.6.0-client-libraries-dotnet"
+ ],
+ "Admin API": [
+ "version-2.6.0-admin-api-overview",
+ "version-2.6.0-admin-api-clusters",
+ "version-2.6.0-admin-api-tenants",
+ "version-2.6.0-admin-api-brokers",
+ "version-2.6.0-admin-api-namespaces",
+ "version-2.6.0-admin-api-permissions",
+ "version-2.6.0-admin-api-persistent-topics",
+ "version-2.6.0-admin-api-non-persistent-topics",
+ "version-2.6.0-admin-api-partitioned-topics",
+ "version-2.6.0-admin-api-non-partitioned-topics",
+ "version-2.6.0-admin-api-schemas",
+ "version-2.6.0-admin-api-functions"
+ ],
+ "Adaptors": [
+ "version-2.6.0-adaptors-kafka",
+ "version-2.6.0-adaptors-spark",
+ "version-2.6.0-adaptors-storm"
+ ],
+ "Cookbooks": [
+ "version-2.6.0-cookbooks-tiered-storage",
+ "version-2.6.0-cookbooks-compaction",
+ "version-2.6.0-cookbooks-deduplication",
+ "version-2.6.0-cookbooks-non-persistent",
+ "version-2.6.0-cookbooks-partitioned",
+ "version-2.6.0-cookbooks-retention-expiry",
+ "version-2.6.0-cookbooks-encryption",
+ "version-2.6.0-cookbooks-message-queue",
+ "version-2.6.0-cookbooks-bookkeepermetadata"
+ ],
+ "Development": [
+ "version-2.6.0-develop-tools",
+ "version-2.6.0-develop-binary-protocol",
+ "version-2.6.0-develop-schema",
+ "version-2.6.0-develop-load-manager",
+ "version-2.6.0-develop-cpp"
+ ],
+ "Reference": [
+ "version-2.6.0-reference-terminology",
+ "version-2.6.0-reference-cli-tools",
+ "version-2.6.0-reference-configuration",
+ "version-2.6.0-reference-metrics"
+ ]
+ },
+ "version-2.6.0-docs-other": {
+ "First Category": [
+ "version-2.6.0-doc4",
+ "version-2.6.0-doc5"
+ ]
+ }
+}