You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pulsar.apache.org by li...@apache.org on 2021/11/09 05:30:27 UTC

[pulsar] branch master updated: [website][upgrade]feat: docs migration - 2.7.1 / Admin API (#12676)

This is an automated email from the ASF dual-hosted git repository.

liuyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/master by this push:
     new 8992712  [website][upgrade]feat: docs migration - 2.7.1 / Admin API (#12676)
8992712 is described below

commit 89927128c5471a7f3a81c19b74f51a368901ff98
Author: Li Li <ur...@gmail.com>
AuthorDate: Tue Nov 9 13:29:29 2021 +0800

    [website][upgrade]feat: docs migration - 2.7.1 / Admin API (#12676)
    
    Signed-off-by: LiLi <ur...@gmail.com>
---
 .../version-2.7.1/admin-api-brokers.md             |  286 +++
 .../version-2.7.1/admin-api-clusters.md            |  372 ++++
 .../version-2.7.1/admin-api-functions.md           | 1016 ++++++++++
 .../version-2.7.1/admin-api-namespaces.md          | 1754 +++++++++++++++++
 .../version-2.7.1/admin-api-overview.md            |  148 ++
 .../version-2.7.1/admin-api-permissions.md         |  205 ++
 .../version-2.7.1/admin-api-tenants.md             |  281 +++
 .../version-2.7.1/admin-api-topics.md              | 2031 ++++++++++++++++++++
 .../versioned_sidebars/version-2.7.1-sidebars.json |   38 +
 9 files changed, 6131 insertions(+)

diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-brokers.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-brokers.md
new file mode 100644
index 0000000..28adfdf
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-brokers.md
@@ -0,0 +1,286 @@
+---
+id: admin-api-brokers
+title: Managing Brokers
+sidebar_label: "Brokers"
+original_id: admin-api-brokers
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+Pulsar brokers consist of two components:
+
+1. An HTTP server exposing a {@inject: rest:REST:/} interface administration and [topic](reference-terminology.md#topic) lookup.
+2. A dispatcher that handles all Pulsar [message](reference-terminology.md#message) transfers.
+
+[Brokers](reference-terminology.md#broker) can be managed via:
+
+* The [`brokers`](reference-pulsar-admin.md#brokers) command of the [`pulsar-admin`](reference-pulsar-admin) tool
+* The `/admin/v2/brokers` endpoint of the admin {@inject: rest:REST:/} API
+* The `brokers` method of the {@inject: javadoc:PulsarAdmin:/admin/org/apache/pulsar/client/admin/PulsarAdmin.html} object in the [Java API](client-libraries-java)
+
+In addition to being configurable when you start them up, brokers can also be [dynamically configured](#dynamic-broker-configuration).
+
+> See the [Configuration](reference-configuration.md#broker) page for a full listing of broker-specific configuration parameters.
+
+## Brokers resources
+
+### List active brokers
+
+Fetch all available active brokers that are serving traffic.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin brokers list use
+
+```
+
+```
+
+broker1.use.org.com:8080
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/:cluster|operation/getActiveBrokers?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.brokers().getActiveBrokers(clusterName)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### list of namespaces owned by a given broker
+
+It finds all namespaces which are owned and served by a given broker.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin brokers namespaces use \
+  --url broker1.use.org.com:8080
+
+```
+
+```json
+
+{
+  "my-property/use/my-ns/0x00000000_0xffffffff": {
+    "broker_assignment": "shared",
+    "is_controlled": false,
+    "is_active": true
+  }
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/:cluster/:broker/ownedNamespaces|operation/getOwnedNamespaes?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.brokers().getOwnedNamespaces(cluster,brokerUrl);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Dynamic broker configuration
+
+One way to configure a Pulsar [broker](reference-terminology.md#broker) is to supply a [configuration](reference-configuration.md#broker) when the broker is [started up](reference-cli-tools.md#pulsar-broker).
+
+But since all broker configuration in Pulsar is stored in ZooKeeper, configuration values can also be dynamically updated *while the broker is running*. When you update broker configuration dynamically, ZooKeeper will notify the broker of the change and the broker will then override any existing configuration values.
+
+* The [`brokers`](reference-pulsar-admin.md#brokers) command for the [`pulsar-admin`](reference-pulsar-admin) tool has a variety of subcommands that enable you to manipulate a broker's configuration dynamically, enabling you to [update config values](#update-dynamic-configuration) and more.
+* In the Pulsar admin {@inject: rest:REST:/} API, dynamic configuration is managed through the `/admin/v2/brokers/configuration` endpoint.
+
+### Update dynamic configuration
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+The [`update-dynamic-config`](reference-pulsar-admin.md#brokers-update-dynamic-config) subcommand will update existing configuration. It takes two arguments: the name of the parameter and the new value using the `config` and `value` flag respectively. Here's an example for the [`brokerShutdownTimeoutMs`](reference-configuration.md#broker-brokerShutdownTimeoutMs) parameter:
+
+```shell
+
+$ pulsar-admin brokers update-dynamic-config --config brokerShutdownTimeoutMs --value 100
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/brokers/configuration/:configName/:configValue|operation/updateDynamicConfiguration?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.brokers().updateDynamicConfiguration(configName, configValue);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List updated values
+
+Fetch a list of all potentially updatable configuration parameters.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin brokers list-dynamic-config
+brokerShutdownTimeoutMs
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/configuration|operation/getDynamicConfigurationName?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.brokers().getDynamicConfigurationNames();
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List all
+
+Fetch a list of all parameters that have been dynamically updated.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin brokers get-all-dynamic-config
+brokerShutdownTimeoutMs:100
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/brokers/configuration/values|operation/getAllDynamicConfigurations?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.brokers().getAllDynamicConfigurations();
+
+```
+
+</TabItem>
+
+</Tabs>
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-clusters.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-clusters.md
new file mode 100644
index 0000000..17aa3a3
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-clusters.md
@@ -0,0 +1,372 @@
+---
+id: admin-api-clusters
+title: Managing Clusters
+sidebar_label: "Clusters"
+original_id: admin-api-clusters
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+Pulsar clusters consist of one or more Pulsar [brokers](reference-terminology.md#broker), one or more [BookKeeper](reference-terminology.md#bookkeeper)
+servers (aka [bookies](reference-terminology.md#bookie)), and a [ZooKeeper](https://zookeeper.apache.org) cluster that provides configuration and coordination management.
+
+Clusters can be managed via:
+
+* The [`clusters`](reference-pulsar-admin.md#clusters) command of the [`pulsar-admin`](reference-pulsar-admin) tool
+* The `/admin/v2/clusters` endpoint of the admin {@inject: rest:REST:/} API
+* The `clusters` method of the {@inject: javadoc:PulsarAdmin:/admin/org/apache/pulsar/client/admin/PulsarAdmin} object in the [Java API](client-libraries-java)
+
+## Clusters resources
+
+### Provision
+
+New clusters can be provisioned using the admin interface.
+
+> Please note that this operation requires superuser privileges.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+You can provision a new cluster using the [`create`](reference-pulsar-admin.md#clusters-create) subcommand. Here's an example:
+
+```shell
+
+$ pulsar-admin clusters create cluster-1 \
+  --url http://my-cluster.org.com:8080 \
+  --broker-url pulsar://my-cluster.org.com:6650
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/clusters/:cluster|operation/createCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+ClusterData clusterData = new ClusterData(
+        serviceUrl,
+        serviceUrlTls,
+        brokerServiceUrl,
+        brokerServiceUrlTls
+);
+admin.clusters().createCluster(clusterName, clusterData);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Initialize cluster metadata
+
+When provision a new cluster, you need to initialize that cluster's [metadata](concepts-architecture-overview.md#metadata-store). When initializing cluster metadata, you need to specify all of the following:
+
+* The name of the cluster
+* The local ZooKeeper connection string for the cluster
+* The configuration store connection string for the entire instance
+* The web service URL for the cluster
+* A broker service URL enabling interaction with the [brokers](reference-terminology.md#broker) in the cluster
+
+You must initialize cluster metadata *before* starting up any [brokers](admin-api-brokers) that will belong to the cluster.
+
+> **No cluster metadata initialization through the REST API or the Java admin API**
+>
+> Unlike most other admin functions in Pulsar, cluster metadata initialization cannot be performed via the admin REST API
+> or the admin Java client, as metadata initialization involves communicating with ZooKeeper directly.
+> Instead, you can use the [`pulsar`](reference-cli-tools.md#pulsar) CLI tool, in particular
+> the [`initialize-cluster-metadata`](reference-cli-tools.md#pulsar-initialize-cluster-metadata) command.
+
+Here's an example cluster metadata initialization command:
+
+```shell
+
+bin/pulsar initialize-cluster-metadata \
+  --cluster us-west \
+  --zookeeper zk1.us-west.example.com:2181 \
+  --configuration-store zk1.us-west.example.com:2184 \
+  --web-service-url http://pulsar.us-west.example.com:8080/ \
+  --web-service-url-tls https://pulsar.us-west.example.com:8443/ \
+  --broker-service-url pulsar://pulsar.us-west.example.com:6650/ \
+  --broker-service-url-tls pulsar+ssl://pulsar.us-west.example.com:6651/
+
+```
+
+You'll need to use `--*-tls` flags only if you're using [TLS authentication](security-tls-authentication) in your instance.
+
+### Get configuration
+
+You can fetch the [configuration](reference-configuration) for an existing cluster at any time.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`get`](reference-pulsar-admin.md#clusters-get) subcommand and specify the name of the cluster. Here's an example:
+
+```shell
+
+$ pulsar-admin clusters get cluster-1
+{
+    "serviceUrl": "http://my-cluster.org.com:8080/",
+    "serviceUrlTls": null,
+    "brokerServiceUrl": "pulsar://my-cluster.org.com:6650/",
+    "brokerServiceUrlTls": null
+    "peerClusterNames": null
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/clusters/:cluster|operation/getCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.clusters().getCluster(clusterName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Update
+
+You can update the configuration for an existing cluster at any time.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`update`](reference-pulsar-admin.md#clusters-update) subcommand and specify new configuration values using flags.
+
+```shell
+
+$ pulsar-admin clusters update cluster-1 \
+  --url http://my-cluster.org.com:4081 \
+  --broker-url pulsar://my-cluster.org.com:3350
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/clusters/:cluster|operation/updateCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+ClusterData clusterData = new ClusterData(
+        serviceUrl,
+        serviceUrlTls,
+        brokerServiceUrl,
+        brokerServiceUrlTls
+);
+admin.clusters().updateCluster(clusterName, clusterData);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete
+
+Clusters can be deleted from a Pulsar [instance](reference-terminology.md#instance).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`delete`](reference-pulsar-admin.md#clusters-delete) subcommand and specify the name of the cluster.
+
+```
+
+$ pulsar-admin clusters delete cluster-1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/clusters/:cluster|operation/deleteCluster?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.clusters().deleteCluster(clusterName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List
+
+You can fetch a list of all clusters in a Pulsar [instance](reference-terminology.md#instance).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`list`](reference-pulsar-admin.md#clusters-list) subcommand.
+
+```shell
+
+$ pulsar-admin clusters list
+cluster-1
+cluster-2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/clusters|operation/getClusters?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.clusters().getClusters();
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Update peer-cluster data
+
+Peer clusters can be configured for a given cluster in a Pulsar [instance](reference-terminology.md#instance).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`update-peer-clusters`](reference-pulsar-admin.md#clusters-update-peer-clusters) subcommand and specify the list of peer-cluster names.
+
+```
+
+$ pulsar-admin update-peer-clusters cluster-1 --peer-clusters cluster-2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/clusters/:cluster/peers|operation/setPeerClusterNames?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.clusters().updatePeerClusterNames(clusterName, peerClusterList);
+
+```
+
+</TabItem>
+
+</Tabs>
\ No newline at end of file
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-functions.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-functions.md
new file mode 100644
index 0000000..6b31c12
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-functions.md
@@ -0,0 +1,1016 @@
+---
+id: admin-api-functions
+title: Manage Functions
+sidebar_label: "Functions"
+original_id: admin-api-functions
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+**Pulsar Functions** are lightweight compute processes that
+
+* consume messages from one or more Pulsar topics
+* apply a user-supplied processing logic to each message
+* publish the results of the computation to another topic
+
+Functions can be managed via the following methods.
+
+Method | Description
+---|---
+**Admin CLI** | The [`functions`](reference-pulsar-admin.md#functions) command of the [`pulsar-admin`](reference-pulsar-admin) tool.
+**REST API** |The `/admin/v3/functions` endpoint of the admin {@inject: rest:REST:/} API.
+**Java Admin API**| The `functions` method of the {@inject: javadoc:PulsarAdmin:/admin/org/apache/pulsar/client/admin/PulsarAdmin} object in the [Java API](client-libraries-java).
+
+## Function resources
+
+You can perform the following operations on functions.
+
+### Create a function
+
+You can create a Pulsar function in cluster mode (deploy it on a Pulsar cluster) using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`create`](reference-pulsar-admin.md#functions-create) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions create \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --inputs test-input-topic \
+  --output persistent://public/default/test-output-topic \
+  --classname org.apache.pulsar.functions.api.examples.ExclamationFunction \
+  --jar /examples/api-examples.jar
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+FunctionConfig functionConfig = new FunctionConfig();
+functionConfig.setTenant(tenant);
+functionConfig.setNamespace(namespace);
+functionConfig.setName(functionName);
+functionConfig.setRuntime(FunctionConfig.Runtime.JAVA);
+functionConfig.setParallelism(1);
+functionConfig.setClassName("org.apache.pulsar.functions.api.examples.ExclamationFunction");
+functionConfig.setProcessingGuarantees(FunctionConfig.ProcessingGuarantees.ATLEAST_ONCE);
+functionConfig.setTopicsPattern(sourceTopicPattern);
+functionConfig.setSubName(subscriptionName);
+functionConfig.setAutoAck(true);
+functionConfig.setOutput(sinkTopic);
+admin.functions().createFunction(functionConfig, fileName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Update a function
+
+You can update a Pulsar function that has been deployed to a Pulsar cluster using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST Admin API",
+    "value": "REST Admin API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`update`](reference-pulsar-admin.md#functions-update) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions update \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --output persistent://public/default/update-output-topic \
+  # other options
+
+```
+
+</TabItem>
+<TabItem value="REST Admin API">
+
+{@inject: endpoint|PUT|/admin/v3/functions/:tenant/:namespace/:functionName?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+FunctionConfig functionConfig = new FunctionConfig();
+functionConfig.setTenant(tenant);
+functionConfig.setNamespace(namespace);
+functionConfig.setName(functionName);
+functionConfig.setRuntime(FunctionConfig.Runtime.JAVA);
+functionConfig.setParallelism(1);
+functionConfig.setClassName("org.apache.pulsar.functions.api.examples.ExclamationFunction");
+UpdateOptions updateOptions = new UpdateOptions();
+updateOptions.setUpdateAuthData(updateAuthData);
+admin.functions().updateFunction(functionConfig, userCodeFile, updateOptions);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Start an instance of a function
+
+You can start a stopped function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`start`](reference-pulsar-admin.md#functions-start) subcommand. 
+
+```shell
+
+$ pulsar-admin functions start \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --instance-id 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/start?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().startFunction(tenant, namespace, functionName, Integer.parseInt(instanceId));
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Start all instances of a function
+
+You can start all stopped function instances using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`start`](reference-pulsar-admin.md#functions-start) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions start \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/start?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.functions().startFunction(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Stop an instance of a function
+
+You can stop a function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`stop`](reference-pulsar-admin.md#functions-stop) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions stop \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --instance-id 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/stop?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().stopFunction(tenant, namespace, functionName, Integer.parseInt(instanceId));
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Stop all instances of a function
+
+You can stop all function instances using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`stop`](reference-pulsar-admin.md#functions-stop) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions stop \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/stop?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().stopFunction(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Restart an instance of a function
+
+Restart a function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`restart`](reference-pulsar-admin.md#functions-restart) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions restart \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --instance-id 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/restart?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().restartFunction(tenant, namespace, functionName, Integer.parseInt(instanceId));
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Restart all instances of a function
+
+You can restart all function instances using Admin CLI, REST API or Java admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`restart`](reference-pulsar-admin.md#functions-restart) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions restart \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/restart?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().restartFunction(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List all functions
+
+You can list all Pulsar functions running under a specific tenant and namespace using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`list`](reference-pulsar-admin.md#functions-list) subcommand.
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions list \
+  --tenant public \
+  --namespace default
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().getFunctions(tenant, namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete a function
+
+You can delete a Pulsar function that is running on a Pulsar cluster using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`delete`](reference-pulsar-admin.md#functions-delete) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions delete \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions)
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v3/functions/:tenant/:namespace/:functionName?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().deleteFunction(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get info about a function
+
+You can get information about a Pulsar function currently running in cluster mode using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`get`](reference-pulsar-admin.md#functions-get) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions get \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions)
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().getFunction(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get status of an instance of a function
+
+You can get the current status of a Pulsar function instance with `instance-id` using Admin CLI, REST API or Java Admin API.
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`status`](reference-pulsar-admin.md#functions-status) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions status \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --instance-id 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/status?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().getFunctionStatus(tenant, namespace, functionName, Integer.parseInt(instanceId));
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get status of all instances of a function
+
+You can get the current status of a Pulsar function instance using Admin CLI, REST API or Java Admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`status`](reference-pulsar-admin.md#functions-status) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions status \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions)
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/status?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().getFunctionStatus(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get stats of an instance of a function
+
+You can get the current stats of a Pulsar Function instance with `instance-id` using Admin CLI, REST API or Java admin API.
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`stats`](reference-pulsar-admin.md#functions-stats) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions stats \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --instance-id 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/:instanceId/stats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().getFunctionStats(tenant, namespace, functionName, Integer.parseInt(instanceId));
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get stats of all instances of a function
+
+You can get the current stats of a Pulsar function using Admin CLI, REST API or Java admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`stats`](reference-pulsar-admin.md#functions-stats) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions stats \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions)
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/stats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().getFunctionStats(tenant, namespace, functionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Trigger a function
+
+You can trigger a specified Pulsar function with a supplied value using Admin CLI, REST API or Java admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`trigger`](reference-pulsar-admin.md#functions-trigger) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions trigger \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --topic (the name of input topic) \
+  --trigger-value \"hello pulsar\"
+  # or --trigger-file (the path of trigger file)
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/trigger?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+admin.functions().triggerFunction(tenant, namespace, functionName, topic, triggerValue, triggerFile);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Put state associated with a function
+
+You can put the state associated with a Pulsar function using Admin CLI, REST API or Java admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin API",
+    "value": "Java Admin API"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`putstate`](reference-pulsar-admin.md#functions-putstate) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions putstate \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --state "{\"key\":\"pulsar\", \"stringValue\":\"hello pulsar\"}"
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v3/functions/:tenant/:namespace/:functionName/state/:key?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin API">
+
+```java
+
+TypeReference<FunctionState> typeRef = new TypeReference<FunctionState>() {};
+FunctionState stateRepr = ObjectMapperFactory.getThreadLocal().readValue(state, typeRef);
+admin.functions().putFunctionState(tenant, namespace, functionName, stateRepr);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Fetch state associated with a function
+
+You can fetch the current state associated with a Pulsar function using Admin CLI, REST API or Java admin API.
+
+<Tabs 
+  defaultValue="Admin CLI"
+  values={[
+  {
+    "label": "Admin CLI",
+    "value": "Admin CLI"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java Admin CLI",
+    "value": "Java Admin CLI"
+  }
+]}>
+<TabItem value="Admin CLI">
+
+Use the [`querystate`](reference-pulsar-admin.md#functions-querystate) subcommand. 
+
+**Example**
+
+```shell
+
+$ pulsar-admin functions querystate \
+  --tenant public \
+  --namespace default \
+  --name (the name of Pulsar Functions) \
+  --key (the key of state)
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v3/functions/:tenant/:namespace/:functionName/state/:key?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java Admin CLI">
+
+```java
+
+admin.functions().getFunctionState(tenant, namespace, functionName, key);
+
+```
+
+</TabItem>
+
+</Tabs>
\ No newline at end of file
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-namespaces.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-namespaces.md
new file mode 100644
index 0000000..e22aec6
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-namespaces.md
@@ -0,0 +1,1754 @@
+---
+id: admin-api-namespaces
+title: Managing Namespaces
+sidebar_label: "Namespaces"
+original_id: admin-api-namespaces
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+Pulsar [namespaces](reference-terminology.md#namespace) are logical groupings of [topics](reference-terminology.md#topic).
+
+Namespaces can be managed via:
+
+* The [`namespaces`](reference-pulsar-admin.md#clusters) command of the [`pulsar-admin`](reference-pulsar-admin) tool
+* The `/admin/v2/namespaces` endpoint of the admin {@inject: rest:REST:/} API
+* The `namespaces` method of the {@inject: javadoc:PulsarAdmin:/admin/org/apache/pulsar/client/admin/PulsarAdmin} object in the [Java API](client-libraries-java)
+
+## Namespaces resources
+
+### Create namespaces
+
+You can create new namespaces under a given [tenant](reference-terminology.md#tenant).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`create`](reference-pulsar-admin.md#namespaces-create) subcommand and specify the namespace by name:
+
+```shell
+
+$ pulsar-admin namespaces create test-tenant/test-namespace
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace|operation/createNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().createNamespace(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get policies
+
+You can fetch the current policies associated with a namespace at any time.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`policies`](reference-pulsar-admin.md#namespaces-policies) subcommand and specify the namespace:
+
+```shell
+
+$ pulsar-admin namespaces policies test-tenant/test-namespace
+{
+  "auth_policies": {
+    "namespace_auth": {},
+    "destination_auth": {}
+  },
+  "replication_clusters": [],
+  "bundles_activated": true,
+  "bundles": {
+    "boundaries": [
+      "0x00000000",
+      "0xffffffff"
+    ],
+    "numBundles": 1
+  },
+  "backlog_quota_map": {},
+  "persistence": null,
+  "latency_stats_sample_rate": {},
+  "message_ttl_in_seconds": 0,
+  "retention_policies": null,
+  "deleted": false
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace|operation/getPolicies?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getPolicies(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List namespaces
+
+You can list all namespaces within a given Pulsar [tenant](reference-terminology.md#tenant).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`list`](reference-pulsar-admin.md#namespaces-list) subcommand and specify the tenant:
+
+```shell
+
+$ pulsar-admin namespaces list test-tenant
+test-tenant/ns1
+test-tenant/ns2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant|operation/getTenantNamespaces?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getNamespaces(tenant);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete namespaces
+
+You can delete existing namespaces from a tenant.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`delete`](reference-pulsar-admin.md#namespaces-delete) subcommand and specify the namespace:
+
+```shell
+
+$ pulsar-admin namespaces delete test-tenant/ns1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace|operation/deleteNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().deleteNamespace(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure replication clusters
+
+#### Set replication cluster
+
+It sets replication clusters for a namespace, so Pulsar can internally replicate publish message from one colo to another colo.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-clusters test-tenant/ns1 \
+  --clusters cl1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/replication|operation/setNamespaceReplicationClusters?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setNamespaceReplicationClusters(namespace, clusters);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get replication cluster
+
+It gives a list of replication clusters for a given namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-clusters test-tenant/cl1/ns1
+
+```
+
+```
+
+cl2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/replication|operation/getNamespaceReplicationClusters?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getNamespaceReplicationClusters(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure backlog quota policies
+
+#### Set backlog quota policies
+
+Backlog quota helps the broker to restrict bandwidth/storage of a namespace once it reaches a certain threshold limit. Admin can set the limit and take corresponding action after the limit is reached.
+
+  1.  producer_request_hold: broker will hold and not persist produce request payload
+
+  2.  producer_exception: broker disconnects with the client by giving an exception.
+
+  3.  consumer_backlog_eviction: broker will start discarding backlog messages
+
+  Backlog quota restriction can be taken care by defining restriction of backlog-quota-type: destination_storage
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-backlog-quota --limit 10 --policy producer_request_hold test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/backlogQuota|operation/setBacklogQuota?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setBacklogQuota(namespace, new BacklogQuota(limit, policy))
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get backlog quota policies
+
+It shows a configured backlog quota for a given namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-backlog-quotas test-tenant/ns1
+
+```
+
+```json
+
+{
+  "destination_storage": {
+    "limit": 10,
+    "policy": "producer_request_hold"
+  }
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/backlogQuotaMap|operation/getBacklogQuotaMap?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getBacklogQuotaMap(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Remove backlog quota policies
+
+It removes backlog quota policies for a given namespace
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces remove-backlog-quota test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/backlogQuota|operation/removeBacklogQuota?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().removeBacklogQuota(namespace, backlogQuotaType)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure persistence policies
+
+#### Set persistence policies
+
+Persistence policies allow to configure persistency-level for all topic messages under a given namespace.
+
+  -   Bookkeeper-ack-quorum: Number of acks (guaranteed copies) to wait for each entry, default: 0
+
+  -   Bookkeeper-ensemble: Number of bookies to use for a topic, default: 0
+
+  -   Bookkeeper-write-quorum: How many writes to make of each entry, default: 0
+
+  -   Ml-mark-delete-max-rate: Throttling rate of mark-delete operation (0 means no throttle), default: 0.0
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-persistence --bookkeeper-ack-quorum 2 --bookkeeper-ensemble 3 --bookkeeper-write-quorum 2 --ml-mark-delete-max-rate 0 test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/persistence|operation/setPersistence?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setPersistence(namespace,new PersistencePolicies(bookkeeperEnsemble, bookkeeperWriteQuorum,bookkeeperAckQuorum,managedLedgerMaxMarkDeleteRate))
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get persistence policies
+
+It shows the configured persistence policies of a given namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-persistence test-tenant/ns1
+
+```
+
+```json
+
+{
+  "bookkeeperEnsemble": 3,
+  "bookkeeperWriteQuorum": 2,
+  "bookkeeperAckQuorum": 2,
+  "managedLedgerMaxMarkDeleteRate": 0
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/persistence|operation/getPersistence?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getPersistence(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure namespace bundles
+
+#### Unload namespace bundles
+
+The namespace bundle is a virtual group of topics which belong to the same namespace. If the broker gets overloaded with the number of bundles, this command can help unload a bundle from that broker, so it can be served by some other less-loaded brokers. The namespace bundle ID ranges from 0x00000000 to 0xffffffff.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces unload --bundle 0x00000000_0xffffffff test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace/{bundle}/unload|operation/unloadNamespaceBundle?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().unloadNamespaceBundle(namespace, bundle)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Split namespace bundles
+
+Each namespace bundle can contain multiple topics and each bundle can be served by only one broker. 
+If a single bundle is creating an excessive load on a broker, an admin splits the bundle using this command permitting one or more of the new bundles to be unloaded thus spreading the load across the brokers.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces split-bundle --bundle 0x00000000_0xffffffff test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace/{bundle}/split|operation/splitNamespaceBundle?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().splitNamespaceBundle(namespace, bundle)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure message TTL
+
+#### Set message-ttl
+
+It configures message’s time to live (in seconds) duration.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-message-ttl --messageTTL 100 test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/messageTTL|operation/setNamespaceMessageTTL?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setNamespaceMessageTTL(namespace, messageTTL)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get message-ttl
+
+It gives a message ttl of configured namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-message-ttl test-tenant/ns1
+
+```
+
+```
+
+100
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/messageTTL|operation/getNamespaceMessageTTL?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getNamespaceMessageTTL(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Remove message-ttl
+
+Remove a message TTL of the configured namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces remove-message-ttl test-tenant/ns1
+
+```
+
+```
+
+100
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/messageTTL|operation/removeNamespaceMessageTTL?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().removeNamespaceMessageTTL(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+
+### Clear backlog
+
+#### Clear namespace backlog
+
+It clears all message backlog for all the topics that belong to a specific namespace. You can also clear backlog for a specific subscription as well.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces clear-backlog --sub my-subscription test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/clearBacklog|operation/clearNamespaceBacklogForSubscription?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().clearNamespaceBacklogForSubscription(namespace, subscription)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Clear bundle backlog
+
+It clears all message backlog for all the topics that belong to a specific NamespaceBundle. You can also clear backlog for a specific subscription as well.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces clear-backlog  --bundle 0x00000000_0xffffffff  --sub my-subscription test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/{bundle}/clearBacklog|operation?version=@pulsar:version_number@/clearNamespaceBundleBacklogForSubscription}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().clearNamespaceBundleBacklogForSubscription(namespace, bundle, subscription)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure retention
+
+#### Set retention
+
+Each namespace contains multiple topics and the retention size (storage size) of each topic should not exceed a specific threshold or it should be stored for a certain period. This command helps configure the retention size and time of topics in a given namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin set-retention --size 10 --time 100 test-tenant/ns1
+
+```
+
+```
+
+N/A
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/retention|operation/setRetention?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setRetention(namespace, new RetentionPolicies(retentionTimeInMin, retentionSizeInMB))
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get retention
+
+It shows retention information of a given namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-retention test-tenant/ns1
+
+```
+
+```json
+
+{
+  "retentionTimeInMinutes": 10,
+  "retentionSizeInMB": 100
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/retention|operation/getRetention?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getRetention(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure dispatch throttling for topics
+
+#### Set dispatch throttling for topics
+
+It sets message dispatch rate for all the topics under a given namespace. 
+The dispatch rate can be restricted by the number of messages per X seconds (`msg-dispatch-rate`) or by the number of message-bytes per X second (`byte-dispatch-rate`).
+dispatch rate is in second and it can be configured with `dispatch-rate-period`. Default value of `msg-dispatch-rate` and `byte-dispatch-rate` is -1 which
+disables the throttling.
+
+:::note
+
+- If neither `clusterDispatchRate` nor `topicDispatchRate` is configured, dispatch throttling is disabled.
+>
+- If `topicDispatchRate` is not configured, `clusterDispatchRate` takes effect.
+> 
+- If `topicDispatchRate` is configured, `topicDispatchRate` takes effect.
+
+:::
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-dispatch-rate test-tenant/ns1 \
+  --msg-dispatch-rate 1000 \
+  --byte-dispatch-rate 1048576 \
+  --dispatch-rate-period 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/dispatchRate|operation/setDispatchRate?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setDispatchRate(namespace, new DispatchRate(1000, 1048576, 1))
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get configured message-rate for topics
+
+It shows configured message-rate for the namespace (topics under this namespace can dispatch this many messages per second)
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-dispatch-rate test-tenant/ns1
+
+```
+
+```json
+
+{
+  "dispatchThrottlingRatePerTopicInMsg" : 1000,
+  "dispatchThrottlingRatePerTopicInByte" : 1048576,
+  "ratePeriodInSecond" : 1
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/dispatchRate|operation/getDispatchRate?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getDispatchRate(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure dispatch throttling for subscription
+
+#### Set dispatch throttling for subscription
+
+It sets message dispatch rate for all the subscription of topics under a given namespace.
+The dispatch rate can be restricted by the number of messages per X seconds (`msg-dispatch-rate`) or by the number of message-bytes per X second (`byte-dispatch-rate`).
+dispatch rate is in second and it can be configured with `dispatch-rate-period`. Default value of `msg-dispatch-rate` and `byte-dispatch-rate` is -1 which
+disables the throttling.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-subscription-dispatch-rate test-tenant/ns1 \
+  --msg-dispatch-rate 1000 \
+  --byte-dispatch-rate 1048576 \
+  --dispatch-rate-period 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/subscriptionDispatchRate|operation/setDispatchRate?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setSubscriptionDispatchRate(namespace, new DispatchRate(1000, 1048576, 1))
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get configured message-rate for subscription
+
+It shows configured message-rate for the namespace (topics under this namespace can dispatch this many messages per second)
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-subscription-dispatch-rate test-tenant/ns1
+
+```
+
+```json
+
+{
+  "dispatchThrottlingRatePerTopicInMsg" : 1000,
+  "dispatchThrottlingRatePerTopicInByte" : 1048576,
+  "ratePeriodInSecond" : 1
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/subscriptionDispatchRate|operation/getDispatchRate?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getSubscriptionDispatchRate(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure dispatch throttling for replicator
+
+#### Set dispatch throttling for replicator
+
+It sets message dispatch rate for all the replicator between replication clusters under a given namespace.
+The dispatch rate can be restricted by the number of messages per X seconds (`msg-dispatch-rate`) or by the number of message-bytes per X second (`byte-dispatch-rate`).
+dispatch rate is in second and it can be configured with `dispatch-rate-period`. Default value of `msg-dispatch-rate` and `byte-dispatch-rate` is -1 which
+disables the throttling.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-replicator-dispatch-rate test-tenant/ns1 \
+  --msg-dispatch-rate 1000 \
+  --byte-dispatch-rate 1048576 \
+  --dispatch-rate-period 1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/replicatorDispatchRate|operation/setDispatchRate?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setReplicatorDispatchRate(namespace, new DispatchRate(1000, 1048576, 1))
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Get configured message-rate for replicator
+
+It shows configured message-rate for the namespace (topics under this namespace can dispatch this many messages per second)
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-replicator-dispatch-rate test-tenant/ns1
+
+```
+
+```json
+
+{
+  "dispatchThrottlingRatePerTopicInMsg" : 1000,
+  "dispatchThrottlingRatePerTopicInByte" : 1048576,
+  "ratePeriodInSecond" : 1
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/replicatorDispatchRate|operation/getDispatchRate?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getReplicatorDispatchRate(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Configure deduplication snapshot interval
+
+#### Get deduplication snapshot interval
+
+It shows configured `deduplicationSnapshotInterval` for a namespace (Each topic under the namespace will take a deduplication snapshot according to this interval)
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces get-deduplication-snapshot-interval test-tenant/ns1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/deduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getDeduplicationSnapshotInterval(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Set deduplication snapshot interval
+
+Set configured `deduplicationSnapshotInterval` for a namespace. Each topic under the namespace will take a deduplication snapshot according to this interval.
+`brokerDeduplicationEnabled` must be set to `true` for this property to take effect.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces set-deduplication-snapshot-interval test-tenant/ns1 --interval 1000
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/deduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+```
+
+```json
+
+{
+  "interval": 1000
+}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().setDeduplicationSnapshotInterval(namespace, 1000)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+#### Remove deduplication snapshot interval
+
+Remove configured `deduplicationSnapshotInterval` of a namespace (Each topic under the namespace will take a deduplication snapshot according to this interval)
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```
+
+$ pulsar-admin namespaces remove-deduplication-snapshot-interval test-tenant/ns1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+```
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/deduplicationSnapshotInterval?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().removeDeduplicationSnapshotInterval(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Namespace isolation
+
+You can use the [Pulsar isolation policy](administration-isolation) to allocate resources (broker and bookie) for a namespace. 
+
+### Unload namespaces from a broker
+
+You can unload a namespace, or a [namespace bundle](reference-terminology.md#namespace-bundle), from the Pulsar [broker](reference-terminology.md#broker) that is currently responsible for it.
+
+#### pulsar-admin
+
+Use the [`unload`](reference-pulsar-admin.md#unload) subcommand of the [`namespaces`](reference-pulsar-admin.md#namespaces) command.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST",
+    "value": "REST"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin namespaces unload my-tenant/my-ns
+
+```
+
+</TabItem>
+<TabItem value="REST">
+
+```
+
+{@inject: endpoint|PUT|/admin/v2/namespaces/:tenant/:namespace/unload|operation/unloadNamespace?version=@pulsar:version_number@}
+
+```
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().unload(namespace)
+
+```
+
+</TabItem>
+
+</Tabs>
\ No newline at end of file
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-overview.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-overview.md
new file mode 100644
index 0000000..3f04c4f
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-overview.md
@@ -0,0 +1,148 @@
+---
+id: admin-api-overview
+title: The Pulsar admin interface
+sidebar_label: "Overview"
+original_id: admin-api-overview
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+The Pulsar admin interface enables you to manage all of the important entities in a Pulsar [instance](reference-terminology.md#instance), such as [tenants](reference-terminology.md#tenant), [topics](reference-terminology.md#topic), and [namespaces](reference-terminology.md#namespace).
+
+You can currently interact with the admin interface via:
+
+- Making HTTP calls against the admin {@inject: rest:REST:/} API provided by Pulsar [brokers](reference-terminology.md#broker). For some restful apis, they might be redirected to topic owner brokers for serving
+   with [`307 Temporary Redirect`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/307), hence the HTTP callers should handle `307 Temporary Redirect`. If you are using `curl`, you should specify `-L`
+   to handle redirections.
+- The `pulsar-admin` CLI tool, which is available in the `bin` folder of your [Pulsar installation](getting-started-standalone):
+
+  ```shell
+  
+  $ bin/pulsar-admin
+  
+  ```
+
+  For the complete commands and descriptions of `pulsar-admin`, see [here](https://pulsar.apache.org/tools/pulsar-admin/2.7.0-SNAPSHOT/).
+
+- A Java client interface.
+
+> #### The REST API is the admin interface
+> Under the hood, both the `pulsar-admin` CLI tool and the Java client both use the REST API. If you’d like to implement your own admin interface client, you should use the REST API as well. Full documentation can be found here.
+
+In this document, examples from each of the three available interfaces will be shown.
+
+## Admin setup
+
+Each of Pulsar's three admin interfaces---the [`pulsar-admin`](reference-pulsar-admin) CLI tool, the [Java admin API](/api/admin), and the {@inject: rest:REST:/} API ---requires some special setup if you have [authentication](security-overview.md#authentication-providers) enabled in your Pulsar [instance](reference-terminology.md#instance).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+If you have [authentication](security-overview.md#authentication-providers) enabled, you will need to provide an auth configuration to use the [`pulsar-admin`](reference-pulsar-admin) tool. By default, the configuration for the `pulsar-admin` tool is found in the [`conf/client.conf`](reference-configuration.md#client) file. Here are the available parameters:
+
+|Name|Description|Default|
+|----|-----------|-------|
+|webServiceUrl|The web URL for the cluster.|http://localhost:8080/|
+|brokerServiceUrl|The Pulsar protocol URL for the cluster.|pulsar://localhost:6650/|
+|authPlugin|The authentication plugin.| |
+|authParams|The authentication parameters for the cluster, as a comma-separated string.| |
+|useTls|Whether or not TLS authentication will be enforced in the cluster.|false|
+|tlsAllowInsecureConnection|Accept untrusted TLS certificate from client.|false|
+|tlsTrustCertsFilePath|Path for the trusted TLS certificate file.| |
+
+</TabItem>
+<TabItem value="REST API">
+
+You can find documentation for the REST API exposed by Pulsar [brokers](reference-terminology.md#broker) in this reference {@inject: rest:document:/}.
+
+</TabItem>
+<TabItem value="Java">
+
+To use the Java admin API, instantiate a {@inject: javadoc:PulsarAdmin:/admin/org/apache/pulsar/client/admin/PulsarAdmin} object, specifying a URL for a Pulsar [broker](reference-terminology.md#broker) and a {@inject: javadoc:PulsarAdminBuilder:/admin/org/apache/pulsar/client/admin/PulsarAdminBuilder}. Here's a minimal example using `localhost`:
+
+```java
+
+String url = "http://localhost:8080";
+// Pass auth-plugin class fully-qualified name if Pulsar-security enabled
+String authPluginClassName = "com.org.MyAuthPluginClass";
+// Pass auth-param if auth-plugin class requires it
+String authParams = "param1=value1";
+boolean useTls = false;
+boolean tlsAllowInsecureConnection = false;
+String tlsTrustCertsFilePath = null;
+PulsarAdmin admin = PulsarAdmin.builder()
+.authentication(authPluginClassName,authParams)
+.serviceHttpUrl(url)
+.tlsTrustCertsFilePath(tlsTrustCertsFilePath)
+.allowTlsInsecureConnection(tlsAllowInsecureConnection)
+.build();
+
+```
+
+If you have multiple brokers to use, you can use multi-host like Pulsar service. For example,
+
+```java
+
+String url = "http://localhost:8080,localhost:8081,localhost:8082";
+// Pass auth-plugin class fully-qualified name if Pulsar-security enabled
+String authPluginClassName = "com.org.MyAuthPluginClass";
+// Pass auth-param if auth-plugin class requires it
+String authParams = "param1=value1";
+boolean useTls = false;
+boolean tlsAllowInsecureConnection = false;
+String tlsTrustCertsFilePath = null;
+PulsarAdmin admin = PulsarAdmin.builder()
+.authentication(authPluginClassName,authParams)
+.serviceHttpUrl(url)
+.tlsTrustCertsFilePath(tlsTrustCertsFilePath)
+.allowTlsInsecureConnection(tlsAllowInsecureConnection)
+.build();
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## How to define Pulsar resource names when running Pulsar in Kubernetes
+
+If you run Pulsar Functions or connectors on Kubernetes, you need to follow Kubernetes naming convention to define the names of your Pulsar resources, whichever admin interface you use.
+
+Kubernetes requires a name that can be used as a DNS subdomain name as defined in [RFC 1123](https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names). Pulsar supports more legal characters than Kubernetes naming convention. If you create a Pulsar resource name with special characters that are not supported by Kubernetes (for example, including colons in a Pulsar namespace name), Kubernetes runtime translates the Pulsar object names into Kubernetes resource labels w [...]
+
+- Truncate to 63 characters
+  
+- Replace the following characters with dashes (-):
+  
+  - Non-alphanumeric characters
+  
+  - Underscores (_)
+  
+  - Dots (.) 
+  
+- Replace beginning and ending non-alphanumeric characters with 0
+  
+:::tip
+
+- If you get an error in translating Pulsar object names into Kubernetes resource labels (for example, you may have a naming collision if your Pulsar object name is too long) or want to customize the translating rules, see [customize Kubernetes runtime](https://pulsar.apache.org/docs/en/next/functions-runtime/#customize-kubernetes-runtime).
+- For how to configure Kubernetes runtime, see [here](https://pulsar.apache.org/docs/en/next/functions-runtime/#configure-kubernetes-runtime).
+
+:::
+
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-permissions.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-permissions.md
new file mode 100644
index 0000000..190122b
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-permissions.md
@@ -0,0 +1,205 @@
+---
+id: admin-api-permissions
+title: Managing permissions
+sidebar_label: "Permissions"
+original_id: admin-api-permissions
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+Permissions in Pulsar are managed at the [namespace](reference-terminology.md#namespace) level
+(that is, within [tenants](reference-terminology.md#tenant) and [clusters](reference-terminology.md#cluster)).
+
+## Grant permissions
+
+You can grant permissions to specific roles for lists of operations such as `produce` and `consume`.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`grant-permission`](reference-pulsar-admin.md#grant-permission) subcommand and specify a namespace, actions using the `--actions` flag, and a role using the `--role` flag:
+
+```shell
+
+$ pulsar-admin namespaces grant-permission test-tenant/ns1 \
+  --actions produce,consume \
+  --role admin10
+
+```
+
+Wildcard authorization can be performed when `authorizationAllowWildcardsMatching` is set to `true` in `broker.conf`.
+
+e.g.
+
+```shell
+
+$ pulsar-admin namespaces grant-permission test-tenant/ns1 \
+                        --actions produce,consume \
+                        --role 'my.role.*'
+
+```
+
+Then, roles `my.role.1`, `my.role.2`, `my.role.foo`, `my.role.bar`, etc. can produce and consume.  
+
+```shell
+
+$ pulsar-admin namespaces grant-permission test-tenant/ns1 \
+                        --actions produce,consume \
+                        --role '*.role.my'
+
+```
+
+Then, roles `1.role.my`, `2.role.my`, `foo.role.my`, `bar.role.my`, etc. can produce and consume.
+
+**Note**: A wildcard matching works at **the beginning or end of the role name only**.
+
+e.g.
+
+```shell
+
+$ pulsar-admin namespaces grant-permission test-tenant/ns1 \
+                        --actions produce,consume \
+                        --role 'my.*.role'
+
+```
+
+In this case, only the role `my.*.role` has permissions.  
+Roles `my.1.role`, `my.2.role`, `my.foo.role`, `my.bar.role`, etc. **cannot** produce and consume.
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/namespaces/:tenant/:namespace/permissions/:role|operation/grantPermissionOnNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().grantPermissionOnNamespace(namespace, role, getAuthActions(actions));
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## Get permissions
+
+You can see which permissions have been granted to which roles in a namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`permissions`](reference-pulsar-admin#permissions) subcommand and specify a namespace:
+
+```shell
+
+$ pulsar-admin namespaces permissions test-tenant/ns1
+{
+  "admin10": [
+    "produce",
+    "consume"
+  ]
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/namespaces/:tenant/:namespace/permissions|operation/getPermissions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().getPermissions(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## Revoke permissions
+
+You can revoke permissions from specific roles, which means that those roles will no longer have access to the specified namespace.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`revoke-permission`](reference-pulsar-admin.md#revoke-permission) subcommand and specify a namespace and a role using the `--role` flag:
+
+```shell
+
+$ pulsar-admin namespaces revoke-permission test-tenant/ns1 \
+  --role admin10
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/permissions/:role|operation/revokePermissionsOnNamespace?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.namespaces().revokePermissionsOnNamespace(namespace, role);
+
+```
+
+</TabItem>
+
+</Tabs>
\ No newline at end of file
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-tenants.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-tenants.md
new file mode 100644
index 0000000..82880d1
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-tenants.md
@@ -0,0 +1,281 @@
+---
+id: admin-api-tenants
+title: Managing Tenants
+sidebar_label: "Tenants"
+original_id: admin-api-tenants
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+Tenants, like namespaces, can be managed using the [admin API](admin-api-overview). There are currently two configurable aspects of tenants:
+
+* Admin roles
+* Allowed clusters
+
+## Tenant resources
+
+### List
+
+You can list all of the tenants associated with an [instance](reference-terminology.md#instance).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`list`](reference-pulsar-admin.md#tenants-list) subcommand.
+
+```shell
+
+$ pulsar-admin tenants list
+my-tenant-1
+my-tenant-2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/tenants|operation/getTenants?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.tenants().getTenants();
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Create
+
+You can create a new tenant.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`create`](reference-pulsar-admin.md#tenants-create) subcommand:
+
+```shell
+
+$ pulsar-admin tenants create my-tenant
+
+```
+
+When creating a tenant, you can assign admin roles using the `-r`/`--admin-roles` flag. You can specify multiple roles as a comma-separated list. Here are some examples:
+
+```shell
+
+$ pulsar-admin tenants create my-tenant \
+  --admin-roles role1,role2,role3
+
+$ pulsar-admin tenants create my-tenant \
+  -r role1
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/tenants/:tenant|operation/createTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.tenants().createTenant(tenantName, tenantInfo);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get configuration
+
+You can fetch the [configuration](reference-configuration) for an existing tenant at any time.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`get`](reference-pulsar-admin.md#tenants-get) subcommand and specify the name of the tenant. Here's an example:
+
+```shell
+
+$ pulsar-admin tenants get my-tenant
+{
+  "adminRoles": [
+    "admin1",
+    "admin2"
+  ],
+  "allowedClusters": [
+    "cl1",
+    "cl2"
+  ]
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/tenants/:cluster|operation/getTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.tenants().getTenantInfo(tenantName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete
+
+Tenants can be deleted from a Pulsar [instance](reference-terminology.md#instance).
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`delete`](reference-pulsar-admin.md#tenants-delete) subcommand and specify the name of the tenant.
+
+```shell
+
+$ pulsar-admin tenants delete my-tenant
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/tenants/:cluster|operation/deleteTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.Tenants().deleteTenant(tenantName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Update
+
+You can update a tenant's configuration.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "JAVA",
+    "value": "JAVA"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+Use the [`update`](reference-pulsar-admin.md#tenants-update) subcommand.
+
+```shell
+
+$ pulsar-admin tenants update my-tenant
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/tenants/:cluster|operation/updateTenant?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="JAVA">
+
+```java
+
+admin.tenants().updateTenant(tenantName, tenantInfo);
+
+```
+
+</TabItem>
+
+</Tabs>
diff --git a/site2/website-next/versioned_docs/version-2.7.1/admin-api-topics.md b/site2/website-next/versioned_docs/version-2.7.1/admin-api-topics.md
new file mode 100644
index 0000000..9b31e22
--- /dev/null
+++ b/site2/website-next/versioned_docs/version-2.7.1/admin-api-topics.md
@@ -0,0 +1,2031 @@
+---
+id: admin-api-topics
+title: Manage topics
+sidebar_label: "Topics"
+original_id: admin-api-topics
+---
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
+
+
+Pulsar has persistent and non-persistent topics. Persistent topic is a logical endpoint for publishing and consuming messages. The topic name structure for persistent topics is:
+
+```shell
+
+persistent://tenant/namespace/topic
+
+```
+
+Non-persistent topics are used in applications that only consume real-time published messages and do not need persistent guarantee. In this way, it reduces message-publish latency by removing overhead of persisting messages. The topic name structure for non-persistent topics is:
+
+```shell
+
+non-persistent://tenant/namespace/topic
+
+```
+
+## Manage topic resources
+Whether it is persistent or non-persistent topic, you can obtain the topic resources through `pulsar-admin` tool, REST API and Java.
+
+:::note
+
+In REST API, `:schema` stands for persistent or non-persistent. `:tenant`, `:namespace`, `:x` are variables, replace them with the real tenant, namespace, and `x` names when using them.     
+Take {@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getList?version=@pulsar:version_number@} as an example, to get the list of persistent topics in REST API, use `https://pulsar.apache.org/admin/v2/persistent/my-tenant/my-namespace`. To get the list of non-persistent topics in REST API, use `https://pulsar.apache.org/admin/v2/non-persistent/my-tenant/my-namespace`.
+
+:::
+
+### List of topics
+
+You can get the list of topics under a given namespace in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics list \
+  my-tenant/my-namespace
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getList?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String namespace = "my-tenant/my-namespace";
+admin.topics().getList(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Grant permission
+
+You can grant permissions on a client role to perform specific actions on a given topic in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics grant-permission \
+  --actions produce,consume --role application1 \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/permissions/:role|operation/grantPermissionsOnTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String role = "test-role";
+Set<AuthAction> actions  = Sets.newHashSet(AuthAction.produce, AuthAction.consume);
+admin.topics().grantPermission(topic, role, actions);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get permission
+
+You can fetch permission in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics permissions \
+  persistent://test-tenant/ns1/tp1 \
+
+{
+    "application1": [
+        "consume",
+        "produce"
+    ]
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/permissions|operation/getPermissionsOnTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getPermissions(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Revoke permission
+
+You can revoke a permission granted on a client role in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics revoke-permission \
+  --role application1 \
+  persistent://test-tenant/ns1/tp1 \
+
+{
+  "application1": [
+    "consume",
+    "produce"
+  ]
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:tenant/:namespace/:topic/permissions/:role|operation/revokePermissionsOnTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String role = "test-role";
+admin.topics().revokePermissions(topic, role);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete topic
+
+You can delete a topic in the following ways. You cannot delete a topic if any active subscription or producers is connected to the topic.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics delete \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:tenant/:namespace/:topic|operation/deleteTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().delete(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Unload topic
+
+You can unload a topic in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics unload \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic/unload|operation/unloadTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().unload(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get stats
+
+You can check the following statistics of a given non-partitioned topic.
+
+  -   **msgRateIn**: The sum of all local and replication publishers' publish rates (msg/s).
+
+  -   **msgThroughputIn**: The sum of all local and replication publishers' publish rates (bytes/s).
+
+  -   **msgRateOut**: The sum of all local and replication consumers' dispatch rates(msg/s).
+
+  -   **msgThroughputOut**: The sum of all local and replication consumers' dispatch rates (bytes/s).
+
+  -   **averageMsgSize**: The average size (in bytes) of messages published within the last interval.
+
+  -   **storageSize**: The sum of the ledgers' storage size for this topic. The space used to store the messages for the topic.
+
+  -   **publishers**: The list of all local publishers into the topic. The list ranges from zero to thousands.
+
+      -   **msgRateIn**: The total rate of messages (msg/s) published by this publisher.
+
+      -   **msgThroughputIn**: The total throughput (bytes/s) of the messages published by this publisher.
+
+      -   **averageMsgSize**: The average message size in bytes from this publisher within the last interval.
+
+      -   **producerId**: The internal identifier for this producer on this topic.
+
+      -   **producerName**: The internal identifier for this producer, generated by the client library.
+
+      -   **address**: The IP address and source port for the connection of this producer.
+
+      -   **connectedSince**: The timestamp when this producer is created or reconnected last time.
+
+  -   **subscriptions**: The list of all local subscriptions to the topic.
+
+      -   **my-subscription**: The name of this subscription. It is defined by the client.
+
+          -   **msgRateOut**: The total rate of messages (msg/s) delivered on this subscription.
+
+          -   **msgThroughputOut**: The total throughput (bytes/s) delivered on this subscription.
+
+          -   **msgBacklog**: The number of messages in the subscription backlog.
+
+          -   **type**: The subscription type.
+
+          -   **msgRateExpired**: The rate at which messages were discarded instead of dispatched from this subscription due to TTL.
+          
+          -   **lastExpireTimestamp**: The timestamp of the last message expire execution.
+          
+          -   **lastConsumedFlowTimestamp**: The timestamp of the last flow command received. 
+          
+          -   **lastConsumedTimestamp**: The latest timestamp of all the consumed timestamp of the consumers.
+          
+          -   **lastAckedTimestamp**: The latest timestamp of all the acked timestamp of the consumers.
+
+          -   **consumers**: The list of connected consumers for this subscription.
+
+                -   **msgRateOut**: The total rate of messages (msg/s) delivered to the consumer.
+
+                -   **msgThroughputOut**: The total throughput (bytes/s) delivered to the consumer.
+
+                -   **consumerName**: The internal identifier for this consumer, generated by the client library.
+
+                -   **availablePermits**: The number of messages that the consumer has space for in the client library's listen queue. `0` means the client library's queue is full and `receive()` isn't being called. A non-zero value means this consumer is ready for dispatched messages.
+
+                -   **unackedMessages**: The number of unacknowledged messages for the consumer.
+
+                -   **blockedConsumerOnUnackedMsgs**: The flag used to verify if the consumer is blocked due to reaching threshold of the unacknowledged messages.
+                
+                -   **lastConsumedTimestamp**: The timestamp when the consumer reads a message the last time. 
+          
+                -   **lastAckedTimestamp**: The timestamp when the consumer acknowledges a message the last time.
+
+  -   **replication**: This section gives the stats for cross-colo replication of this topic
+
+      -   **msgRateIn**: The total rate (msg/s) of messages received from the remote cluster. 
+
+      -   **msgThroughputIn**: The total throughput (bytes/s) received from the remote cluster.
+
+      -   **msgRateOut**: The total rate of messages (msg/s) delivered to the replication-subscriber.
+
+      -   **msgThroughputOut**: The total throughput (bytes/s) delivered to the replication-subscriber.
+
+      -   **msgRateExpired**: The total rate of messages (msg/s) expired.
+
+      -   **replicationBacklog**: The number of messages pending to be replicated to remote cluster.
+
+      -   **connected**: Whether the outbound replicator is connected.
+
+      -   **replicationDelayInSeconds**: How long the oldest message has been waiting to be sent through the connection, if connected is `true`.
+
+      -   **inboundConnection**: The IP and port of the broker in the remote cluster's publisher connection to this broker.
+
+      -   **inboundConnectedSince**: The TCP connection being used to publish messages to the remote cluster. If there are no local publishers connected, this connection is automatically closed after a minute.
+
+      -   **outboundConnection**: The address of the outbound replication connection.
+
+      -   **outboundConnectedSince**: The timestamp of establishing outbound connection.
+
+The following is an example of a topic status.
+
+```json
+
+{
+  "msgRateIn": 4641.528542257553,
+  "msgThroughputIn": 44663039.74947473,
+  "msgRateOut": 0,
+  "msgThroughputOut": 0,
+  "averageMsgSize": 1232439.816728665,
+  "storageSize": 135532389160,
+  "publishers": [
+    {
+      "msgRateIn": 57.855383881403576,
+      "msgThroughputIn": 558994.7078932219,
+      "averageMsgSize": 613135,
+      "producerId": 0,
+      "producerName": null,
+      "address": null,
+      "connectedSince": null
+    }
+  ],
+  "subscriptions": {
+    "my-topic_subscription": {
+      "msgRateOut": 0,
+      "msgThroughputOut": 0,
+      "msgBacklog": 116632,
+      "type": null,
+      "msgRateExpired": 36.98245516804671,
+      "consumers": []
+    }
+  },
+  "replication": {}
+}
+
+```
+
+To get the status of a topic, you can use the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics stats \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/stats|operation/getStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getStats(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get internal stats
+
+You can get the detailed statistics of a topic.
+
+  -   **entriesAddedCounter**: Messages published since this broker loaded this topic.
+
+  -   **numberOfEntries**: The total number of messages being tracked.
+
+  -   **totalSize**: The total storage size in bytes of all messages.
+
+  -   **currentLedgerEntries**: The count of messages written to the ledger that is currently open for writing.
+
+  -   **currentLedgerSize**: The size in bytes of messages written to the ledger that is currently open for writing.
+
+  -   **lastLedgerCreatedTimestamp**: The time when the last ledger is created.
+
+  -   **lastLedgerCreationFailureTimestamp:** The time when the last ledger failed.
+
+  -   **waitingCursorsCount**: The number of cursors that are "caught up" and waiting for a new message to be published.
+
+  -   **pendingAddEntriesCount**: The number of messages that complete (asynchronous) write requests.
+
+  -   **lastConfirmedEntry**: The ledgerid:entryid of the last message that is written successfully. If the entryid is `-1`, then the ledger is open, yet no entries are written.
+
+  -   **state**: The state of this ledger for writing. The state `LedgerOpened` means that a ledger is open for saving published messages.
+
+  -   **ledgers**: The ordered list of all ledgers for this topic holding messages.
+
+      -   **ledgerId**: The ID of this ledger.
+
+      -   **entries**: The total number of entries belong to this ledger.
+
+      -   **size**: The size of messages written to this ledger (in bytes).
+
+      -   **offloaded**: Whether this ledger is offloaded.
+
+  -   **compactedLedger**: The ledgers holding un-acked messages after topic compaction.
+ 
+      -   **ledgerId**: The ID of this ledger.
+     
+      -   **entries**: The total number of entries belong to this ledger.
+     
+      -   **size**: The size of messages written to this ledger (in bytes).
+     
+      -   **offloaded**: Whether this ledger is offloaded. The value is `false` for the compacted topic ledger.
+      
+  -   **cursors**: The list of all cursors on this topic. Each subscription in the topic stats has a cursor.
+
+      -   **markDeletePosition**: All messages before the markDeletePosition are acknowledged by the subscriber.
+
+      -   **readPosition**: The latest position of subscriber for reading message.
+
+      -   **waitingReadOp**: This is true when the subscription has read the latest message published to the topic and is waiting for new messages to be published.
+
+      -   **pendingReadOps**: The counter for how many outstanding read requests to the BookKeepers in progress.
+
+      -   **messagesConsumedCounter**: The number of messages this cursor has acked since this broker loaded this topic.
+
+      -   **cursorLedger**: The ledger being used to persistently store the current markDeletePosition.
+
+      -   **cursorLedgerLastEntry**: The last entryid used to persistently store the current markDeletePosition.
+
+      -   **individuallyDeletedMessages**: If acknowledges are being done out of order, the ranges of messages acknowledged between the markDeletePosition and the read-position shows.
+
+      -   **lastLedgerSwitchTimestamp**: The last time the cursor ledger is rolled over.
+
+      -   **state**: The state of the cursor ledger: `Open` means you have a cursor ledger for saving updates of the markDeletePosition.
+
+The following is an example of the detailed statistics of a topic.
+
+```json
+
+{
+    "entriesAddedCounter": 20449518,
+    "numberOfEntries": 3233,
+    "totalSize": 331482,
+    "currentLedgerEntries": 3233,
+    "currentLedgerSize": 331482,
+    "lastLedgerCreatedTimestamp": "2016-06-29 03:00:23.825",
+    "lastLedgerCreationFailureTimestamp": null,
+    "waitingCursorsCount": 1,
+    "pendingAddEntriesCount": 0,
+    "lastConfirmedEntry": "324711539:3232",
+    "state": "LedgerOpened",
+    "ledgers": [
+        {
+            "ledgerId": 324711539,
+            "entries": 0,
+            "size": 0,
+            "offloaded": true
+        }
+    ],
+    "compactedLedger": {
+        "ledgerId": 324711540,
+        "entries": 10,
+        "size": 100,
+        "offloaded": false
+    },
+    "cursors": {
+        "my-subscription": {
+            "markDeletePosition": "324711539:3133",
+            "readPosition": "324711539:3233",
+            "waitingReadOp": true,
+            "pendingReadOps": 0,
+            "messagesConsumedCounter": 20449501,
+            "cursorLedger": 324702104,
+            "cursorLedgerLastEntry": 21,
+            "individuallyDeletedMessages": "[(324711539:3134‥324711539:3136], (324711539:3137‥324711539:3140], ]",
+            "lastLedgerSwitchTimestamp": "2016-06-29 01:30:19.313",
+            "state": "Open"
+        }
+    }
+}
+
+```
+
+To get the internal status of a topic, you can use the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics stats-internal \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/internalStats|operation/getInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getInternalStats(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Peek messages
+
+You can peek a number of messages for a specific subscription of a given topic in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics peek-messages \
+  --count 10 --subscription my-subscription \
+  persistent://test-tenant/ns1/tp1 \
+
+Message ID: 315674752:0
+Properties:  {  "X-Pulsar-publish-time" : "2015-07-13 17:40:28.451"  }
+msg-payload
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/position/:messagePosition|operation?version=@pulsar:version_number@/peekNthMessage}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+int numMessages = 1;
+admin.topics().peekMessages(topic, subName, numMessages);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get message by ID
+
+You can fetch the message with the given ledger ID and entry ID in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ ./bin/pulsar-admin topics get-message-by-id \
+  persistent://public/default/my-topic \
+  -l 10 -e 0
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/ledger/:ledgerId/entry/:entryId|operation/getMessageById?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+long ledgerId = 10;
+long entryId = 10;
+admin.topics().getMessageById(topic, ledgerId, entryId);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Skip messages
+
+You can skip a number of messages for a specific subscription of a given topic in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics skip \
+  --count 10 --subscription my-subscription \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/skip/:numMessages|operation/skipMessages?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+int numMessages = 1;
+admin.topics().skipMessages(topic, subName, numMessages);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Skip all messages
+
+You can skip all the old messages for a specific subscription of a given topic.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics skip-all \
+  --subscription my-subscription \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/skip_all|operation/skipAllMessages?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+admin.topics().skipAllMessages(topic, subName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Reset cursor
+
+You can reset a subscription cursor position back to the position which is recorded X minutes before. It essentially calculates time and position of cursor at X minutes before and resets it at that position. You can reset the cursor in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics reset-cursor \
+  --subscription my-subscription --time 10 \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic/subscription/:subName/resetcursor/:timestamp|operation/resetCursor?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subName = "my-subscription";
+long timestamp = 2342343L;
+admin.topics().skipAllMessages(topic, subName, timestamp);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Lookup of topic
+
+You can locate the broker URL which is serving the given topic in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics lookup \
+  persistent://test-tenant/ns1/tp1 \
+
+ "pulsar://broker1.org.com:4480"
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/lookup/v2/topic/:schema/:tenant:namespace/:topic|/?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.lookup().lookupDestination(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get bundle
+
+You can check the range of the bundle which contains given topic in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics bundle-range \
+  persistent://test-tenant/ns1/tp1 \
+
+ "0x00000000_0xffffffff"
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/lookup/v2/topic/:topic_domain/:tenant/:namespace/:topic/bundle|/?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.lookup().getBundleRange(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get subscriptions
+
+You can check all subscription names for a given topic in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics subscriptions \
+  persistent://test-tenant/ns1/tp1 \
+
+ my-subscription
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/subscriptions|operation/getSubscriptions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getSubscriptions(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Unsubscribe
+
+When a subscription does not process messages any more, you can unsubscribe it in the following ways. 
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics unsubscribe \
+  --subscription my-subscription \
+  persistent://test-tenant/ns1/tp1 \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/namespaces/:tenant/:namespace/:topic/subscription/:subscription|operation/deleteSubscription?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+String subscriptionName = "my-subscription";
+admin.topics().deleteSubscription(topic, subscriptionName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Last Message Id
+
+You can get the last committed message ID for a persistent topic. It is available since 2.3.0 release.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+pulsar-admin topics last-message-id topic-name
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|Get|/admin/v2/:schema/:tenant/:namespace/:topic/lastMessageId?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```Java
+
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getLastMessage(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## Manage non-partitioned topics
+You can use Pulsar [admin API](admin-api-overview) to create, delete and check status of non-partitioned topics.
+
+### Create
+Non-partitioned topics must be explicitly created. When creating a new non-partitioned topic, you need to provide a name for the topic.
+
+By default, 60 seconds after creation, topics are considered inactive and deleted automatically to avoid generating trash data. To disable this feature, set `brokerDeleteInactiveTopicsEnabled` to `false`. To change the frequency of checking inactive topics, set `brokerDeleteInactiveTopicsFrequencySeconds` to a specific value.
+
+For more information about the two parameters, see [here](reference-configuration.md#broker).
+
+You can create non-partitioned topics in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+When you create non-partitioned topics with the [`create`](reference-pulsar-admin.md#create-3) command, you need to specify the topic name as an argument.
+
+```shell
+
+$ bin/pulsar-admin topics create \
+  persistent://my-tenant/my-namespace/my-topic
+
+```
+
+:::note
+
+When you create a non-partitioned topic with the suffix '-partition-' followed by numeric value like 'xyz-topic-partition-x' for the topic name, if a partitioned topic with same suffix 'xyz-topic-partition-y' exists, then the numeric value(x) for the non-partitioned topic must be larger than the number of partitions(y) of the partitioned topic. Otherwise, you cannot create such a non-partitioned topic. 
+
+:::
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic|operation/createNonPartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().createNonPartitionedTopic(topicName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete
+You can delete non-partitioned topics in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ bin/pulsar-admin topics delete \
+  persistent://my-tenant/my-namespace/my-topic
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:tenant/:namespace/:topic|operation/deleteTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().delete(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List
+
+You can get the list of topics under a given namespace in the following ways.  
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics list tenant/namespace
+persistent://tenant/namespace/topic1
+persistent://tenant/namespace/topic2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getList?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().getList(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Stats
+
+You can check the current statistics of a given topic. The following is an example. For description of each stats, refer to [get stats](#get-stats).
+
+```json
+
+{
+  "msgRateIn": 4641.528542257553,
+  "msgThroughputIn": 44663039.74947473,
+  "msgRateOut": 0,
+  "msgThroughputOut": 0,
+  "averageMsgSize": 1232439.816728665,
+  "storageSize": 135532389160,
+  "publishers": [
+    {
+      "msgRateIn": 57.855383881403576,
+      "msgThroughputIn": 558994.7078932219,
+      "averageMsgSize": 613135,
+      "producerId": 0,
+      "producerName": null,
+      "address": null,
+      "connectedSince": null
+    }
+  ],
+  "subscriptions": {
+    "my-topic_subscription": {
+      "msgRateOut": 0,
+      "msgThroughputOut": 0,
+      "msgBacklog": 116632,
+      "type": null,
+      "msgRateExpired": 36.98245516804671,
+      "consumers": []
+    }
+  },
+  "replication": {}
+}
+
+```
+
+You can check the current statistics of a given topic and its connected producers and consumers in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics stats \
+  persistent://test-tenant/namespace/topic \
+  --get-precise-backlog
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/stats|operation/getStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().getStats(topic, false /* is precise backlog */);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## Manage partitioned topics
+You can use Pulsar [admin API](admin-api-overview) to create, update, delete and check status of partitioned topics.
+
+### Create
+
+Partitioned topics must be explicitly created. When creating a new partitioned topic, you need to provide a name and the number of partitions for the topic.
+
+By default, 60 seconds after creation, topics are considered inactive and deleted automatically to avoid generating trash data. To disable this feature, set `brokerDeleteInactiveTopicsEnabled` to `false`. To change the frequency of checking inactive topics, set `brokerDeleteInactiveTopicsFrequencySeconds` to a specific value.
+
+For more information about the two parameters, see [here](reference-configuration.md#broker).
+
+You can create partitioned topics in the following ways.
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+When you create partitioned topics with the [`create-partitioned-topic`](reference-pulsar-admin.md#create-partitioned-topic)
+command, you need to specify the topic name as an argument and the number of partitions using the `-p` or `--partitions` flag.
+
+```shell
+
+$ bin/pulsar-admin topics create-partitioned-topic \
+  persistent://my-tenant/my-namespace/my-topic \
+  --partitions 4
+
+```
+
+:::note
+
+If a non-partitioned topic with the suffix '-partition-' followed by a numeric value like 'xyz-topic-partition-10', you can not create a partitioned topic with name 'xyz-topic', because the partitions of the partitioned topic could override the existing non-partitioned topic. To create such partitioned topic, you have to delete that non-partitioned topic first.
+
+:::
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|PUT|/admin/v2/:schema/:tenant/:namespace/:topic/partitions|operation/createPartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+int numPartitions = 4;
+admin.topics().createPartitionedTopic(topicName, numPartitions);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Create missed partitions
+
+When topic auto-creation is disabled, and you have a partitioned topic without any partitions, you can use the [`create-missed-partitions`](reference-pulsar-admin.md#create-missed-partitions) command to create partitions for the topic.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+You can create missed partitions with the [`create-missed-partitions`](reference-pulsar-admin.md#create-missed-partitions) command and specify the topic name as an argument.
+
+```shell
+
+$ bin/pulsar-admin topics create-missed-partitions \
+  persistent://my-tenant/my-namespace/my-topic \
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:namespace/:topic|operation/createMissedPartitions?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().createMissedPartitions(topicName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Get metadata
+
+Partitioned topics are associated with metadata, you can view it as a JSON object. The following metadata field is available.
+
+Field | Description
+:-----|:-------
+`partitions` | The number of partitions into which the topic is divided.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+You can check the number of partitions in a partitioned topic with the [`get-partitioned-topic-metadata`](reference-pulsar-admin.md#get-partitioned-topic-metadata) subcommand. 
+
+```shell
+
+$ pulsar-admin topics get-partitioned-topic-metadata \
+  persistent://my-tenant/my-namespace/my-topic
+{
+  "partitions": 4
+}
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/partitions|operation/getPartitionedMetadata?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+String topicName = "persistent://my-tenant/my-namespace/my-topic";
+admin.topics().getPartitionedTopicMetadata(topicName);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Update
+
+You can update the number of partitions for an existing partitioned topic *if* the topic is non-global. However, you can only add the partition number. Decrementing the number of partitions would delete the topic, which is not supported in Pulsar.
+
+Producers and consumers can find the newly created partitions automatically.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+You can update partitioned topics with the [`update-partitioned-topic`](reference-pulsar-admin.md#update-partitioned-topic) command.
+
+```shell
+
+$ pulsar-admin topics update-partitioned-topic \
+  persistent://my-tenant/my-namespace/my-topic \
+  --partitions 8
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|POST|/admin/v2/:schema/:tenant/:cluster/:namespace/:destination/partitions|operation/updatePartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().updatePartitionedTopic(topic, numPartitions);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Delete
+You can delete partitioned topics with the [`delete-partitioned-topic`](reference-pulsar-admin.md#delete-partitioned-topic) command, REST API and Java. 
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ bin/pulsar-admin topics delete-partitioned-topic \
+  persistent://my-tenant/my-namespace/my-topic
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|DELETE|/admin/v2/:schema/:topic/:namespace/:destination/partitions|operation/deletePartitionedTopic?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().delete(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### List
+You can get the list of topics under a given namespace in the following ways.  
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics list tenant/namespace
+persistent://tenant/namespace/topic1
+persistent://tenant/namespace/topic2
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace|operation/getPartitionedTopicList?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().getList(namespace);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Stats
+
+You can check the current statistics of a given partitioned topic. The following is an example. For description of each stats, refer to [get stats](#get-stats).
+
+```json
+
+{
+  "msgRateIn" : 999.992947159793,
+  "msgThroughputIn" : 1070918.4635439808,
+  "msgRateOut" : 0.0,
+  "msgThroughputOut" : 0.0,
+  "bytesInCounter" : 270318763,
+  "msgInCounter" : 252489,
+  "bytesOutCounter" : 0,
+  "msgOutCounter" : 0,
+  "averageMsgSize" : 1070.926056966454,
+  "msgChunkPublished" : false,
+  "storageSize" : 270316646,
+  "backlogSize" : 200921133,
+  "publishers" : [ {
+    "msgRateIn" : 999.992947159793,
+    "msgThroughputIn" : 1070918.4635439808,
+    "averageMsgSize" : 1070.3333333333333,
+    "chunkedMessageRate" : 0.0,
+    "producerId" : 0
+  } ],
+  "subscriptions" : {
+    "test" : {
+      "msgRateOut" : 0.0,
+      "msgThroughputOut" : 0.0,
+      "bytesOutCounter" : 0,
+      "msgOutCounter" : 0,
+      "msgRateRedeliver" : 0.0,
+      "chuckedMessageRate" : 0,
+      "msgBacklog" : 144318,
+      "msgBacklogNoDelayed" : 144318,
+      "blockedSubscriptionOnUnackedMsgs" : false,
+      "msgDelayed" : 0,
+      "unackedMessages" : 0,
+      "msgRateExpired" : 0.0,
+      "lastExpireTimestamp" : 0,
+      "lastConsumedFlowTimestamp" : 0,
+      "lastConsumedTimestamp" : 0,
+      "lastAckedTimestamp" : 0,
+      "consumers" : [ ],
+      "isDurable" : true,
+      "isReplicated" : false
+    }
+  },
+  "replication" : { },
+  "metadata" : {
+    "partitions" : 3
+  },
+  "partitions" : { }
+}
+
+```
+
+You can check the current statistics of a given partitioned topic and its connected producers and consumers in the following ways. 
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics partitioned-stats \
+  persistent://test-tenant/namespace/topic \
+  --per-partition
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/partitioned-stats|operation/getPartitionedStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().getPartitionedStats(topic, true /* per partition */, false /* is precise backlog */);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+### Internal stats
+
+You can check the detailed statistics of a topic. The following is an example. For description of each stats, refer to [get internal stats](#get-internal-stats).
+
+```json
+
+{
+  "entriesAddedCounter": 20449518,
+  "numberOfEntries": 3233,
+  "totalSize": 331482,
+  "currentLedgerEntries": 3233,
+  "currentLedgerSize": 331482,
+  "lastLedgerCreatedTimestamp": "2016-06-29 03:00:23.825",
+  "lastLedgerCreationFailureTimestamp": null,
+  "waitingCursorsCount": 1,
+  "pendingAddEntriesCount": 0,
+  "lastConfirmedEntry": "324711539:3232",
+  "state": "LedgerOpened",
+  "ledgers": [
+    {
+      "ledgerId": 324711539,
+      "entries": 0,
+      "size": 0
+    }
+  ],
+  "cursors": {
+    "my-subscription": {
+      "markDeletePosition": "324711539:3133",
+      "readPosition": "324711539:3233",
+      "waitingReadOp": true,
+      "pendingReadOps": 0,
+      "messagesConsumedCounter": 20449501,
+      "cursorLedger": 324702104,
+      "cursorLedgerLastEntry": 21,
+      "individuallyDeletedMessages": "[(324711539:3134‥324711539:3136], (324711539:3137‥324711539:3140], ]",
+      "lastLedgerSwitchTimestamp": "2016-06-29 01:30:19.313",
+      "state": "Open"
+    }
+  }
+}
+
+```
+
+You can get the internal stats for the partitioned topic in the following ways.
+
+<Tabs 
+  defaultValue="pulsar-admin"
+  values={[
+  {
+    "label": "pulsar-admin",
+    "value": "pulsar-admin"
+  },
+  {
+    "label": "REST API",
+    "value": "REST API"
+  },
+  {
+    "label": "Java",
+    "value": "Java"
+  }
+]}>
+<TabItem value="pulsar-admin">
+
+```shell
+
+$ pulsar-admin topics stats-internal \
+  persistent://test-tenant/namespace/topic
+
+```
+
+</TabItem>
+<TabItem value="REST API">
+
+{@inject: endpoint|GET|/admin/v2/:schema/:tenant/:namespace/:topic/internalStats|operation/getInternalStats?version=@pulsar:version_number@}
+
+</TabItem>
+<TabItem value="Java">
+
+```java
+
+admin.topics().getInternalStats(topic);
+
+```
+
+</TabItem>
+
+</Tabs>
+
+## Publish to partitioned topics
+
+By default, Pulsar topics are served by a single broker, which limits the maximum throughput of a topic. *Partitioned topics* can span multiple brokers and thus allow for higher throughput. 
+
+You can publish to partitioned topics using Pulsar client libraries. When publishing to partitioned topics, you must specify a routing mode. If you do not specify any routing mode when you create a new producer, the round robin routing mode is used. 
+
+### Routing mode
+
+You can specify the routing mode in the ProducerConfiguration object that you use to configure your producer. The routing mode determines which partition(internal topic) that each message should be published to.
+
+The following {@inject: javadoc:MessageRoutingMode:/client/org/apache/pulsar/client/api/MessageRoutingMode} options are available.
+
+Mode     | Description 
+:--------|:------------
+`RoundRobinPartition` | If no key is provided, the producer publishes messages across all partitions in round-robin policy to achieve the maximum throughput. Round-robin is not done per individual message, round-robin is set to the same boundary of batching delay to ensure that batching is effective. If a key is specified on the message, the partitioned producer hashes the key and assigns message to a particular partition. This is the default mode. 
+`SinglePartition`     | If no key is provided, the producer picks a single partition randomly and publishes all messages into that partition. If a key is specified on the message, the partitioned producer hashes the key and assigns message to a particular partition.
+`CustomPartition`     | Use custom message router implementation that is called to determine the partition for a particular message. You can create a custom routing mode by using the Java client and implementing the {@inject: javadoc:MessageRouter:/client/org/apache/pulsar/client/api/MessageRouter} interface.
+
+The following is an example:
+
+```java
+
+String pulsarBrokerRootUrl = "pulsar://localhost:6650";
+String topic = "persistent://my-tenant/my-namespace/my-topic";
+
+PulsarClient pulsarClient = PulsarClient.builder().serviceUrl(pulsarBrokerRootUrl).build();
+Producer<byte[]> producer = pulsarClient.newProducer()
+        .topic(topic)
+        .messageRoutingMode(MessageRoutingMode.SinglePartition)
+        .create();
+producer.send("Partitioned topic message".getBytes());
+
+```
+
+### Custom message router
+
+To use a custom message router, you need to provide an implementation of the {@inject: javadoc:MessageRouter:/client/org/apache/pulsar/client/api/MessageRouter} interface, which has just one `choosePartition` method:
+
+```java
+
+public interface MessageRouter extends Serializable {
+    int choosePartition(Message msg);
+}
+
+```
+
+The following router routes every message to partition 10:
+
+```java
+
+public class AlwaysTenRouter implements MessageRouter {
+    public int choosePartition(Message msg) {
+        return 10;
+    }
+}
+
+```
+
+With that implementation, you can send
+
+```java
+
+String pulsarBrokerRootUrl = "pulsar://localhost:6650";
+String topic = "persistent://my-tenant/my-cluster-my-namespace/my-topic";
+
+PulsarClient pulsarClient = PulsarClient.builder().serviceUrl(pulsarBrokerRootUrl).build();
+Producer<byte[]> producer = pulsarClient.newProducer()
+        .topic(topic)
+        .messageRouter(new AlwaysTenRouter())
+        .create();
+producer.send("Partitioned topic message".getBytes());
+
+```
+
+### How to choose partitions when using a key
+If a message has a key, it supersedes the round robin routing policy. The following example illustrates how to choose the partition when using a key.
+
+```java
+
+// If the message has a key, it supersedes the round robin routing policy
+        if (msg.hasKey()) {
+            return signSafeMod(hash.makeHash(msg.getKey()), topicMetadata.numPartitions());
+        }
+
+        if (isBatchingEnabled) { // if batching is enabled, choose partition on `partitionSwitchMs` boundary.
+            long currentMs = clock.millis();
+            return signSafeMod(currentMs / partitionSwitchMs + startPtnIdx, topicMetadata.numPartitions());
+        } else {
+            return signSafeMod(PARTITION_INDEX_UPDATER.getAndIncrement(this), topicMetadata.numPartitions());
+        }
+
+```
+
+        
\ No newline at end of file
diff --git a/site2/website-next/versioned_sidebars/version-2.7.1-sidebars.json b/site2/website-next/versioned_sidebars/version-2.7.1-sidebars.json
index b8aa773..59952a8 100644
--- a/site2/website-next/versioned_sidebars/version-2.7.1-sidebars.json
+++ b/site2/website-next/versioned_sidebars/version-2.7.1-sidebars.json
@@ -435,6 +435,44 @@
           "id": "version-2.7.1/client-libraries-dotnet"
         }
       ]
+    },
+    {
+      "type": "category",
+      "label": "Admin API",
+      "items": [
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-overview"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-clusters"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-tenants"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-brokers"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-namespaces"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-permissions"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-topics"
+        },
+        {
+          "type": "doc",
+          "id": "version-2.7.1/admin-api-functions"
+        }
+      ]
     }
   ]
 }
\ No newline at end of file