Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[website][upgrade]feat: website upgrade / docs migration - 2.8.1 #13442

Merged
merged 1 commit into from
Dec 23, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions site2/website-next/docusaurus.config.js
Original file line number Diff line number Diff line change
@@ -135,6 +135,10 @@ module.exports = {
to: "docs",
position: "right",
items: [
{
label: "2.8.1",
to: "docs/",
},
{
label: "2.8.0",
to: "docs/",
274 changes: 274 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/adaptors-kafka.md

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/adaptors-spark.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
---
id: adaptors-spark
title: Pulsar adaptor for Apache Spark
sidebar_label: "Apache Spark"
original_id: adaptors-spark
---

## Spark Streaming receiver
The Spark Streaming receiver for Pulsar is a custom receiver that enables Apache [Spark Streaming](https://spark.apache.org/streaming/) to receive raw data from Pulsar.

An application can receive data in [Resilient Distributed Dataset](https://spark.apache.org/docs/latest/programming-guide.html#resilient-distributed-datasets-rdds) (RDD) format via the Spark Streaming receiver and can process it in a variety of ways.

### Prerequisites

To use the receiver, include a dependency for the `pulsar-spark` library in your Java configuration.

#### Maven

If you're using Maven, add this to your `pom.xml`:

```xml

<!-- in your <properties> block -->
<pulsar.version>@pulsar:version@</pulsar.version>

<!-- in your <dependencies> block -->
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-spark</artifactId>
<version>${pulsar.version}</version>
</dependency>

```

#### Gradle

If you're using Gradle, add this to your `build.gradle` file:

```groovy
def pulsarVersion = "@pulsar:version@"
dependencies {
compile group: 'org.apache.pulsar', name: 'pulsar-spark', version: pulsarVersion
}
```

### Usage

Pass an instance of `SparkStreamingPulsarReceiver` to the `receiverStream` method in `JavaStreamingContext`:

```java

String serviceUrl = "pulsar://localhost:6650/";
String topic = "persistent://public/default/test_src";
String subs = "test_sub";

SparkConf sparkConf = new SparkConf().setMaster("local[*]").setAppName("Pulsar Spark Example");

JavaStreamingContext jsc = new JavaStreamingContext(sparkConf, Durations.seconds(60));

ConsumerConfigurationData<byte[]> pulsarConf = new ConsumerConfigurationData();

Set<String> set = new HashSet();
set.add(topic);
pulsarConf.setTopicNames(set);
pulsarConf.setSubscriptionName(subs);

SparkStreamingPulsarReceiver pulsarReceiver = new SparkStreamingPulsarReceiver(
serviceUrl,
pulsarConf,
new AuthenticationDisabled());

JavaReceiverInputDStream<byte[]> lineDStream = jsc.receiverStream(pulsarReceiver);

```

For a complete example, click [here](https://github.com/apache/pulsar-adapters/blob/master/examples/spark/src/main/java/org/apache/spark/streaming/receiver/example/SparkStreamingPulsarReceiverExample.java). In this example, the number of messages that contain the string "Pulsar" in received messages is counted.

Note that if needed, other Pulsar authentication classes can be used. For example, in order to use a token during authentication the following parameters for the `SparkStreamingPulsarReceiver` constructor can be set:

```java

SparkStreamingPulsarReceiver pulsarReceiver = new SparkStreamingPulsarReceiver(
serviceUrl,
pulsarConf,
new AuthenticationToken("token:<secret-JWT-token>"));

```

96 changes: 96 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/adaptors-storm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
id: adaptors-storm
title: Pulsar adaptor for Apache Storm
sidebar_label: "Apache Storm"
original_id: adaptors-storm
---

Pulsar Storm is an adaptor for integrating with [Apache Storm](http://storm.apache.org/) topologies. It provides core Storm implementations for sending and receiving data.

An application can inject data into a Storm topology via a generic Pulsar spout, as well as consume data from a Storm topology via a generic Pulsar bolt.

## Using the Pulsar Storm Adaptor

Include dependency for Pulsar Storm Adaptor:

```xml

<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-storm</artifactId>
<version>${pulsar.version}</version>
</dependency>

```

## Pulsar Spout

The Pulsar Spout allows for the data published on a topic to be consumed by a Storm topology. It emits a Storm tuple based on the message received and the `MessageToValuesMapper` provided by the client.

The tuples that fail to be processed by the downstream bolts will be re-injected by the spout with an exponential backoff, within a configurable timeout (the default is 60 seconds) or a configurable number of retries, whichever comes first, after which it is acknowledged by the consumer. Here's an example construction of a spout:

```java

MessageToValuesMapper messageToValuesMapper = new MessageToValuesMapper() {

@Override
public Values toValues(Message msg) {
return new Values(new String(msg.getData()));
}

@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
// declare the output fields
declarer.declare(new Fields("string"));
}
};

// Configure a Pulsar Spout
PulsarSpoutConfiguration spoutConf = new PulsarSpoutConfiguration();
spoutConf.setServiceUrl("pulsar://broker.messaging.usw.example.com:6650");
spoutConf.setTopic("persistent://my-property/usw/my-ns/my-topic1");
spoutConf.setSubscriptionName("my-subscriber-name1");
spoutConf.setMessageToValuesMapper(messageToValuesMapper);

// Create a Pulsar Spout
PulsarSpout spout = new PulsarSpout(spoutConf);

```

For a complete example, click [here](https://github.com/apache/pulsar-adapters/blob/master/pulsar-storm/src/test/java/org/apache/pulsar/storm/PulsarSpoutTest.java).

## Pulsar Bolt

The Pulsar bolt allows data in a Storm topology to be published on a topic. It publishes messages based on the Storm tuple received and the `TupleToMessageMapper` provided by the client.

A partitioned topic can also be used to publish messages on different topics. In the implementation of the `TupleToMessageMapper`, a "key" will need to be provided in the message which will send the messages with the same key to the same topic. Here's an example bolt:

```java

TupleToMessageMapper tupleToMessageMapper = new TupleToMessageMapper() {

@Override
public TypedMessageBuilder<byte[]> toMessage(TypedMessageBuilder<byte[]> msgBuilder, Tuple tuple) {
String receivedMessage = tuple.getString(0);
// message processing
String processedMsg = receivedMessage + "-processed";
return msgBuilder.value(processedMsg.getBytes());
}

@Override
public void declareOutputFields(OutputFieldsDeclarer declarer) {
// declare the output fields
}
};

// Configure a Pulsar Bolt
PulsarBoltConfiguration boltConf = new PulsarBoltConfiguration();
boltConf.setServiceUrl("pulsar://broker.messaging.usw.example.com:6650");
boltConf.setTopic("persistent://my-property/usw/my-ns/my-topic2");
boltConf.setTupleToMessageMapper(tupleToMessageMapper);

// Create a Pulsar Bolt
PulsarBolt bolt = new PulsarBolt(boltConf);

```

262 changes: 262 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-brokers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
---
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>

### Get the information of the leader broker

Fetch the information of the leader broker, for example, the service url.

<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 leader-broker

```

```
BrokerInfo(serviceUrl=broker1.use.org.com:8080)
```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|GET|/admin/v2/brokers/leaderBroker?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

```java

admin.brokers().getLeaderBroker()

```

For the detail of the code above, see [here](https://github.com/apache/pulsar/blob/master/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/BrokersImpl.java#L80)

</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>
294 changes: 294 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-clusters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,294 @@
---
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>
782 changes: 782 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-functions.md

Large diffs are not rendered by default.

1,364 changes: 1,364 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-namespaces.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
id: admin-api-non-partitioned-topics
title: Managing non-partitioned topics
sidebar_label: "Non-partitioned topics"
original_id: admin-api-non-partitioned-topics
---

For details of the content, refer to [manage topics](admin-api-topics).
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
id: admin-api-non-persistent-topics
title: Managing non-persistent topics
sidebar_label: "Non-Persistent topics"
original_id: admin-api-non-persistent-topics
---

For details of the content, refer to [manage topics](admin-api-topics).
129 changes: 129 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
id: admin-api-overview
title: 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 important entities in a Pulsar instance, such as tenants, topics, and namespaces.

You can interact with the admin interface via:

- HTTP calls, which are made against the admin {@inject: rest:REST:/} API provided by Pulsar brokers. For some RESTful APIs, they might be redirected to the 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 use `curl` commands, you should specify `-L` to handle redirections.
- A Java client interface.
- The `pulsar-admin` CLI tool, which is available in the `bin` folder of your Pulsar installation:

```shell

$ bin/pulsar-admin

```

For complete commands of `pulsar-admin` tool, see [Pulsar admin snapshot](https://pulsar.apache.org/tools/pulsar-admin/).


> **The REST API is the admin interface**. Both the `pulsar-admin` CLI tool and the Java client use the REST API. If you implement your own admin interface client, you should use the REST API.
## Admin setup

Each of the three admin interfaces (the `pulsar-admin` CLI tool, the {@inject: rest:REST:/} API, and the [Java admin API](/api/admin)) requires some special setup if you have enabled authentication in your Pulsar 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 enabled authentication, you need to provide an auth configuration to use the `pulsar-admin` tool. By default, the configuration for the `pulsar-admin` tool is in the [`conf/client.conf`](reference-configuration.md#client) file. The following 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 details for the REST API exposed by Pulsar brokers in this {@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, and specify a URL for a Pulsar broker and a {@inject: javadoc:PulsarAdminBuilder:/admin/org/apache/pulsar/client/admin/PulsarAdminBuilder}. The following is 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 use multiple brokers, 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 which are in RFC 1123-compliant forms. Consequently, you can run functions or connectors using Kubernetes runtime. The rules for translating Pulsar object names into Kubernetes resource labels are as below:

- 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).

:::

365 changes: 365 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-packages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,365 @@
---
id: admin-api-packages
title: Manage packages
sidebar_label: "Packages"
original_id: admin-api-packages
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';


Package management enables version management and simplifies the upgrade and rollback processes for Functions, Sinks, and Sources. When you use the same function, sink and source in different namespaces, you can upload them to a common package management system.

## Package name

A `package` is identified by five parts: `type`, `tenant`, `namespace`, `package name`, and `version`.

| Part | Description |
|-------|-------------|
|`type` |The type of the package. The following types are supported: `function`, `sink` and `source`. |
| `name`|The fully qualified name of the package: `<tenant>/<namespace>/<package name>`.|
|`version`|The version of the package.|

The following is a code sample.

```java

class PackageName {
private final PackageType type;
private final String namespace;
private final String tenant;
private final String name;
private final String version;
}

enum PackageType {
FUNCTION("function"), SINK("sink"), SOURCE("source");
}

```

## Package URL
A package is located using a URL. The package URL is written in the following format:

```shell

<type>://<tenant>/<namespace>/<package name>@<version>

```

The following are package URL examples:

`sink://public/default/mysql-sink@1.0`
`function://my-tenant/my-ns/my-function@0.1`
`source://my-tenant/my-ns/mysql-cdc-source@2.3`

The package management system stores the data, versions and metadata of each package. The metadata is shown in the following table.

| metadata | Description |
|----------|-------------|
|description|The description of the package.|
|contact |The contact information of a package. For example, team email.|
|create_time| The time when the package is created.|
|modification_time| The time when the package is modified.|
|properties |A key/value map that stores your own information.|

## Permissions

The packages are organized by the tenant and namespace, so you can apply the tenant and namespace permissions to packages directly.

## Package resources
You can use the package management with command line tools, REST API and Java client.

### Upload a package
You can upload a package to the package management service 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 packages upload function://public/default/example@v0.1 --path package-file --description package-description

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|POST|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

Upload a package to the package management service synchronously.

```java

void upload(PackageMetadata metadata, String packageName, String path) throws PulsarAdminException;

```

Upload a package to the package management service asynchronously.

```java

CompletableFuture<Void> uploadAsync(PackageMetadata metadata, String packageName, String path);

```

</TabItem>

</Tabs>

### Download a package
You can download a package to the package management service 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 packages download function://public/default/example@v0.1 --path package-file

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|GET|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

Download a package to the package management service synchronously.

```java

void download(String packageName, String path) throws PulsarAdminException;

```

Download a package to the package management service asynchronously.

```java

CompletableFuture<Void> downloadAsync(String packageName, String path);

```

</TabItem>

</Tabs>

### List all versions of a package
You can get a list of all versions of a package 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 packages list --type function public/default

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|GET|/admin/v3/packages/:type/:tenant/:namespace/:packageName/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

List all versions of a package synchronously.

```java

List<String> listPackageVersions(String packageName) throws PulsarAdminException;

```

List all versions of a package asynchronously.

```java

CompletableFuture<List<String>> listPackageVersionsAsync(String packageName);

```

</TabItem>

</Tabs>

### List all the specified type packages under a namespace
You can get a list of all the packages with the given type in a 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

bin/pulsar-admin packages list --type function public/default

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|PUT|/admin/v3/packages/:type/:tenant/:namespace/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

List all the packages with the given type in a namespace synchronously.

```java

List<String> listPackages(String type, String namespace) throws PulsarAdminException;

```

List all the packages with the given type in a namespace asynchronously.

```java

CompletableFuture<List<String>> listPackagesAsync(String type, String namespace);

```

</TabItem>

</Tabs>

### Get the metadata of a package
You can get the metadata of a package 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 packages get-metadata function://public/default/test@v1

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|GET|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/metadata/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

Get the metadata of a package synchronously.

```java

PackageMetadata getMetadata(String packageName) throws PulsarAdminException;

```

Get the metadata of a package asynchronously.

```java

CompletableFuture<PackageMetadata> getMetadataAsync(String packageName);

```

</TabItem>

</Tabs>

### Update the metadata of a package
You can update the metadata of a package 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 packages update-metadata function://public/default/example@v0.1 --description update-description

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|PUT|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/metadata/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

Update a package metadata information synchronously.

```java

void updateMetadata(String packageName, PackageMetadata metadata) throws PulsarAdminException;

```

Update a package metadata information asynchronously.

```java

CompletableFuture<Void> updateMetadataAsync(String packageName, PackageMetadata metadata);

```

</TabItem>

</Tabs>

### Delete a specified package
You can delete a specified package with its package name 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">

The following command example deletes a package of version 0.1.

```shell

bin/pulsar-admin packages delete function://public/default/example@v0.1

```

</TabItem>
<TabItem value="REST API">

{@inject: endpoint|DELETE|/admin/v3/packages/:type/:tenant/:namespace/:packageName/:version/?version=@pulsar:version_number@}

</TabItem>
<TabItem value="JAVA">

Delete a specified package synchronously.

```java

void delete(String packageName) throws PulsarAdminException;

```

Delete a specified package asynchronously.

```java

CompletableFuture<Void> deleteAsync(String packageName);

```

</TabItem>

</Tabs>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
id: admin-api-partitioned-topics
title: Managing partitioned topics
sidebar_label: "Partitioned topics"
original_id: admin-api-partitioned-topics
---

For details of the content, refer to [manage topics](admin-api-topics).
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
---
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
id: admin-api-persistent-topics
title: Managing persistent topics
sidebar_label: "Persistent topics"
original_id: admin-api-persistent-topics
---

For details of the content, refer to [manage topics](admin-api-topics).
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
id: admin-api-schemas
title: Managing Schemas
sidebar_label: "Schemas"
original_id: admin-api-schemas
---

216 changes: 216 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-tenants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
---
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>
1,739 changes: 1,739 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/admin-api-topics.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
id: administration-dashboard
title: Pulsar dashboard
sidebar_label: "Dashboard"
original_id: administration-dashboard
---

:::note

Pulsar dashboard is deprecated. If you want to manage and monitor the stats of your topics, use [Pulsar Manager](administration-pulsar-manager).

:::

Pulsar dashboard is a web application that enables users to monitor current stats for all [topics](reference-terminology.md#topic) in tabular form.

The dashboard is a data collector that polls stats from all the brokers in a Pulsar instance (across multiple clusters) and stores all the information in a [PostgreSQL](https://www.postgresql.org/) database.

You can use the [Django](https://www.djangoproject.com) web app to render the collected data.

## Install

The easiest way to use the dashboard is to run it inside a [Docker](https://www.docker.com/products/docker) container.

```shell

$ SERVICE_URL=http://broker.example.com:8080/
$ docker run -p 80:80 \
-e SERVICE_URL=$SERVICE_URL \
apachepulsar/pulsar-dashboard:@pulsar:version@

```

You can find the {@inject: github:Dockerfile:/dashboard/Dockerfile} in the `dashboard` directory and build an image from scratch as well:

```shell

$ docker build -t apachepulsar/pulsar-dashboard dashboard

```

If token authentication is enabled:
> Provided token should have super-user access.
```shell

$ SERVICE_URL=http://broker.example.com:8080/
$ JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
$ docker run -p 80:80 \
-e SERVICE_URL=$SERVICE_URL \
-e JWT_TOKEN=$JWT_TOKEN \
apachepulsar/pulsar-dashboard

```


You need to specify only one service URL for a Pulsar cluster. Internally, the collector figures out all the existing clusters and the brokers from where it needs to pull the metrics. If you connect the dashboard to Pulsar running in standalone mode, the URL is `http://<broker-ip>:8080` by default. `<broker-ip>` is the ip address or hostname of the machine running Pulsar standalone. The ip address or hostname should be accessible from the docker instance running dashboard.

Once the Docker container runs, the web dashboard is accessible via `localhost` or whichever host that Docker uses.

> The `SERVICE_URL` that the dashboard uses needs to be reachable from inside the Docker container
If the Pulsar service runs in standalone mode in `localhost`, the `SERVICE_URL` has to
be the IP of the machine.

Similarly, given the Pulsar standalone advertises itself with localhost by default, you need to
explicitly set the advertise address to the host IP. For example:

```shell

$ bin/pulsar standalone --advertised-address 1.2.3.4

```

### Known issues

Currently, only Pulsar Token [authentication](security-overview.md#authentication-providers) is supported.
215 changes: 215 additions & 0 deletions site2/website-next/versioned_docs/version-2.8.1/administration-geo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
---
id: administration-geo
title: Pulsar geo-replication
sidebar_label: "Geo-replication"
original_id: administration-geo
---

*Geo-replication* is the replication of persistently stored message data across multiple clusters of a Pulsar instance.

## How geo-replication works

The diagram below illustrates the process of geo-replication across Pulsar clusters:

![Replication Diagram](/assets/geo-replication.png)

In this diagram, whenever **P1**, **P2**, and **P3** producers publish messages to the **T1** topic on **Cluster-A**, **Cluster-B**, and **Cluster-C** clusters respectively, those messages are instantly replicated across clusters. Once the messages are replicated, **C1** and **C2** consumers can consume those messages from their respective clusters.

Without geo-replication, **C1** and **C2** consumers are not able to consume messages that **P3** producer publishes.

## Geo-replication and Pulsar properties

You must enable geo-replication on a per-tenant basis in Pulsar. You can enable geo-replication between clusters only when a tenant is created that allows access to both clusters.

Although geo-replication must be enabled between two clusters, actually geo-replication is managed at the namespace level. You must complete the following tasks to enable geo-replication for a namespace:

* [Enable geo-replication namespaces](#enable-geo-replication-namespaces)
* Configure that namespace to replicate across two or more provisioned clusters

Any message published on *any* topic in that namespace is replicated to all clusters in the specified set.

## Local persistence and forwarding

When messages are produced on a Pulsar topic, messages are first persisted in the local cluster, and then forwarded asynchronously to the remote clusters.

In normal cases, when connectivity issues are none, messages are replicated immediately, at the same time as they are dispatched to local consumers. Typically, the network [round-trip time](https://en.wikipedia.org/wiki/Round-trip_delay_time) (RTT) between the remote regions defines end-to-end delivery latency.

Applications can create producers and consumers in any of the clusters, even when the remote clusters are not reachable (like during a network partition).

Producers and consumers can publish messages to and consume messages from any cluster in a Pulsar instance. However, subscriptions cannot only be local to the cluster where the subscriptions are created but also can be transferred between clusters after replicated subscription is enabled. Once replicated subscription is enabled, you can keep subscription state in synchronization. Therefore, a topic can be asynchronously replicated across multiple geographical regions. In case of failover, a consumer can restart consuming messages from the failure point in a different cluster.

In the aforementioned example, the **T1** topic is replicated among three clusters, **Cluster-A**, **Cluster-B**, and **Cluster-C**.

All messages produced in any of the three clusters are delivered to all subscriptions in other clusters. In this case, **C1** and **C2** consumers receive all messages that **P1**, **P2**, and **P3** producers publish. Ordering is still guaranteed on a per-producer basis.

## Configure replication

As stated in [Geo-replication and Pulsar properties](#geo-replication-and-pulsar-properties) section, geo-replication in Pulsar is managed at the [tenant](reference-terminology.md#tenant) level.

The following example connects three clusters: **us-east**, **us-west**, and **us-cent**.

### Connect replication clusters

To replicate data among clusters, you need to configure each cluster to connect to the other. You can use the [`pulsar-admin`](https://pulsar.apache.org/tools/pulsar-admin/) tool to create a connection.

**Example**

Suppose that you have 3 replication clusters: `us-west`, `us-cent`, and `us-east`.

1. Configure the connection from `us-west` to `us-east`.

Run the following command on `us-west`.

```shell

$ bin/pulsar-admin clusters create \
--broker-url pulsar://<DNS-OF-US-EAST>:<PORT> \
--url http://<DNS-OF-US-EAST>:<PORT> \
us-east

```

:::tip

- If you want to use a secure connection for a cluster, you can use the flags `--broker-url-secure` and `--url-secure`. For more information, see [pulsar-admin clusters create](https://pulsar.apache.org/tools/pulsar-admin/).
- Different clusters may have different authentications. You can use the authentication flag `--auth-plugin` and `--auth-parameters` together to set cluster authentication, which overrides `brokerClientAuthenticationPlugin` and `brokerClientAuthenticationParameters` if `authenticationEnabled` sets to `true` in `broker.conf` and `standalone.conf`. For more information, see [authentication and authorization](concepts-authentication).

:::

2. Configure the connection from `us-west` to `us-cent`.

Run the following command on `us-west`.

```shell

$ bin/pulsar-admin clusters create \
--broker-url pulsar://<DNS-OF-US-CENT>:<PORT> \
--url http://<DNS-OF-US-CENT>:<PORT> \
us-cent

```

3. Run similar commands on `us-east` and `us-cent` to create connections among clusters.

### Grant permissions to properties

To replicate to a cluster, the tenant needs permission to use that cluster. You can grant permission to the tenant when you create the tenant or grant later.

Specify all the intended clusters when you create a tenant:

```shell

$ bin/pulsar-admin tenants create my-tenant \
--admin-roles my-admin-role \
--allowed-clusters us-west,us-east,us-cent

```

To update permissions of an existing tenant, use `update` instead of `create`.

### Enable geo-replication namespaces

You can create a namespace with the following command sample.

```shell

$ bin/pulsar-admin namespaces create my-tenant/my-namespace

```

Initially, the namespace is not assigned to any cluster. You can assign the namespace to clusters using the `set-clusters` subcommand:

```shell

$ bin/pulsar-admin namespaces set-clusters my-tenant/my-namespace \
--clusters us-west,us-east,us-cent

```

You can change the replication clusters for a namespace at any time, without disruption to ongoing traffic. Replication channels are immediately set up or stopped in all clusters as soon as the configuration changes.

### Use topics with geo-replication

Once you create a geo-replication namespace, any topics that producers or consumers create within that namespace is replicated across clusters. Typically, each application uses the `serviceUrl` for the local cluster.

#### Selective replication

By default, messages are replicated to all clusters configured for the namespace. You can restrict replication selectively by specifying a replication list for a message, and then that message is replicated only to the subset in the replication list.

The following is an example for the [Java API](client-libraries-java). Note the use of the `setReplicationClusters` method when you construct the {@inject: javadoc:Message:/client/org/apache/pulsar/client/api/Message} object:

```java

List<String> restrictReplicationTo = Arrays.asList(
"us-west",
"us-east"
);

Producer producer = client.newProducer()
.topic("some-topic")
.create();

producer.newMessage()
.value("my-payload".getBytes())
.setReplicationClusters(restrictReplicationTo)
.send();

```

#### Topic stats

Topic-specific statistics for geo-replication topics are available via the [`pulsar-admin`](reference-pulsar-admin) tool and {@inject: rest:REST:/} API:

```shell

$ bin/pulsar-admin persistent stats persistent://my-tenant/my-namespace/my-topic

```

Each cluster reports its own local stats, including the incoming and outgoing replication rates and backlogs.

#### Delete a geo-replication topic

Given that geo-replication topics exist in multiple regions, directly deleting a geo-replication topic is not possible. Instead, you should rely on automatic topic garbage collection.

In Pulsar, a topic is automatically deleted when the topic meets the following three conditions:
- no producers or consumers are connected to it;
- no subscriptions to it;
- no more messages are kept for retention.
For geo-replication topics, each region uses a fault-tolerant mechanism to decide when deleting the topic locally is safe.

You can explicitly disable topic garbage collection by setting `brokerDeleteInactiveTopicsEnabled` to `false` in your [broker configuration](reference-configuration.md#broker).

To delete a geo-replication topic, close all producers and consumers on the topic, and delete all of its local subscriptions in every replication cluster. When Pulsar determines that no valid subscription for the topic remains across the system, it will garbage collect the topic.

## Replicated subscriptions

Pulsar supports replicated subscriptions, so you can keep subscription state in sync, within a sub-second timeframe, in the context of a topic that is being asynchronously replicated across multiple geographical regions.

In case of failover, a consumer can restart consuming from the failure point in a different cluster.

### Enable replicated subscription

Replicated subscription is disabled by default. You can enable replicated subscription when creating a consumer.

```java

Consumer<String> consumer = client.newConsumer(Schema.STRING)
.topic("my-topic")
.subscriptionName("my-subscription")
.replicateSubscriptionState(true)
.subscribe();

```

### Advantages

* It is easy to implement the logic.
* You can choose to enable or disable replicated subscription.
* When you enable it, the overhead is low, and it is easy to configure.
* When you disable it, the overhead is zero.

### Limitations

* When you enable replicated subscription, you're creating a consistent distributed snapshot to establish an association between message ids from different clusters. The snapshots are taken periodically. The default value is `1 second`. It means that a consumer failing over to a different cluster can potentially receive 1 second of duplicates. You can also configure the frequency of the snapshot in the `broker.conf` file.
* Only the base line cursor position is synced in replicated subscriptions while the individual acknowledgments are not synced. This means the messages acknowledged out-of-order could end up getting delivered again, in the case of a cluster failover.
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
id: administration-isolation
title: Pulsar isolation
sidebar_label: "Pulsar isolation"
original_id: administration-isolation
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';


In an organization, a Pulsar instance provides services to multiple teams. When organizing the resources across multiple teams, you want to make a suitable isolation plan to avoid the resource competition between different teams and applications and provide high-quality messaging service. In this case, you need to take resource isolation into consideration and weigh your intended actions against expected and unexpected consequences.

To enforce resource isolation, you can use the Pulsar isolation policy, which allows you to allocate resources (**broker** and **bookie**) for the namespace.

## Broker isolation

In Pulsar, when namespaces (more specifically, namespace bundles) are assigned dynamically to brokers, the namespace isolation policy limits the set of brokers that can be used for assignment. Before topics are assigned to brokers, you can set the namespace isolation policy with a primary or a secondary regex to select desired brokers.

You can set a namespace isolation policy for a cluster using one of the following methods.

<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">

```
pulsar-admin ns-isolation-policy set options
```

For more information about the command `pulsar-admin ns-isolation-policy set options`, see [here](https://pulsar.apache.org/tools/pulsar-admin/).

**Example**

```shell

bin/pulsar-admin ns-isolation-policy set \
--auto-failover-policy-type min_available \
--auto-failover-policy-params min_limit=1,usage_threshold=80 \
--namespaces my-tenant/my-namespace \
--primary 10.193.216.* my-cluster policy-name

```

</TabItem>
<TabItem value="REST API">

[PUT /admin/v2/namespaces/{tenant}/{namespace}](https://pulsar.apache.org/admin-rest-api/?version=master&apiversion=v2#operation/createNamespace)

</TabItem>
<TabItem value="Java admin API">

For how to set namespace isolation policy using Java admin API, see [here](https://github.com/apache/pulsar/blob/master/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java#L251).

</TabItem>

</Tabs>

## Bookie isolation

A namespace can be isolated into user-defined groups of bookies, which guarantees all the data that belongs to the namespace is stored in desired bookies. The bookie affinity group uses the BookKeeper [rack-aware placement policy](https://bookkeeper.apache.org/docs/latest/api/javadoc/org/apache/bookkeeper/client/EnsemblePlacementPolicy.html) and it is a way to feed rack information which is stored as JSON format in znode.

You can set a bookie affinity group using one of the following methods.

<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">

```
pulsar-admin namespaces set-bookie-affinity-group options
```

For more information about the command `pulsar-admin namespaces set-bookie-affinity-group options`, see [here](https://pulsar.apache.org/tools/pulsar-admin/).

**Example**

```shell

bin/pulsar-admin bookies set-bookie-rack \
--bookie 127.0.0.1:3181 \
--hostname 127.0.0.1:3181 \
--group group-bookie1 \
--rack rack1

bin/pulsar-admin namespaces set-bookie-affinity-group public/default \
--primary-group group-bookie1

```

</TabItem>
<TabItem value="REST API">

[POST /admin/v2/namespaces/{tenant}/{namespace}/persistence/bookieAffinity](https://pulsar.apache.org/admin-rest-api/?version=master&apiversion=v2#operation/setBookieAffinityGroup)

</TabItem>
<TabItem value="Java admin API">

For how to set bookie affinity group for a namespace using Java admin API, see [here](https://github.com/apache/pulsar/blob/master/pulsar-client-admin/src/main/java/org/apache/pulsar/client/admin/internal/NamespacesImpl.java#L1164).

</TabItem>

</Tabs>
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
---
id: administration-load-balance
title: Pulsar load balance
sidebar_label: "Load balance"
original_id: administration-load-balance
---

## Load balance across Pulsar brokers

Pulsar is an horizontally scalable messaging system, so the traffic
in a logical cluster must be spread across all the available Pulsar brokers as evenly as possible, which is a core requirement.

You can use multiple settings and tools to control the traffic distribution which require a bit of context to understand how the traffic is managed in Pulsar. Though, in most cases, the core requirement mentioned above is true out of the box and you should not worry about it.

## Pulsar load manager architecture

The following part introduces the basic architecture of the Pulsar load manager.

### Assign topics to brokers dynamically

Topics are dynamically assigned to brokers based on the load conditions of all brokers in the cluster.

When a client starts using new topics that are not assigned to any broker, a process is triggered to choose the best suited broker to acquire ownership of these topics according to the load conditions.

In case of partitioned topics, different partitions are assigned to different brokers. Here "topic" means either a non-partitioned topic or one partition of a topic.

The assignment is "dynamic" because the assignment changes quickly. For example, if the broker owning the topic crashes, the topic is reassigned immediately to another broker. Another scenario is that the broker owning the topic becomes overloaded. In this case, the topic is reassigned to a less loaded broker.

The stateless nature of brokers makes the dynamic assignment possible, so you can quickly expand or shrink the cluster based on usage.

#### Assignment granularity

The assignment of topics or partitions to brokers is not done at the topics or partitions level, but done at the Bundle level (a higher level). The reason is to amortize the amount of information that you need to keep track. Based on CPU, memory, traffic load and other indexes, topics are assigned to a particular broker dynamically.

Instead of individual topic or partition assignment, each broker takes ownership of a subset of the topics for a namespace. This subset is called a "*bundle*" and effectively this subset is a sharding mechanism.

The namespace is the "administrative" unit: many config knobs or operations are done at the namespace level.

For assignment, a namespaces is sharded into a list of "bundles", with each bundle comprising
a portion of overall hash range of the namespace.

Topics are assigned to a particular bundle by taking the hash of the topic name and checking in which
bundle the hash falls into.

Each bundle is independent of the others and thus is independently assigned to different brokers.

### Create namespaces and bundles

When you create a new namespace, the new namespace sets to use the default number of bundles. You can set this in `conf/broker.conf`:

```properties

# When a namespace is created without specifying the number of bundle, this
# value will be used as the default
defaultNumberOfNamespaceBundles=4

```

You can either change the system default, or override it when you create a new namespace:

```shell

$ bin/pulsar-admin namespaces create my-tenant/my-namespace --clusters us-west --bundles 16

```

With this command, you create a namespace with 16 initial bundles. Therefore the topics for this namespaces can immediately be spread across up to 16 brokers.

In general, if you know the expected traffic and number of topics in advance, you had better start with a reasonable number of bundles instead of waiting for the system to auto-correct the distribution.

On the same note, it is beneficial to start with more bundles than the number of brokers, because of the hashing nature of the distribution of topics into bundles. For example, for a namespace with 1000 topics, using something like 64 bundles achieves a good distribution of traffic across 16 brokers.

### Unload topics and bundles

You can "unload" a topic in Pulsar with admin operation. Unloading means to close the topics,
release ownership and reassign the topics to a new broker, based on current load.

When unloading happens, the client experiences a small latency blip, typically in the order of tens of milliseconds, while the topic is reassigned.

Unloading is the mechanism that the load-manager uses to perform the load shedding, but you can also trigger the unloading manually, for example to correct the assignments and redistribute traffic even before having any broker overloaded.

Unloading a topic has no effect on the assignment, but just closes and reopens the particular topic:

```shell

pulsar-admin topics unload persistent://tenant/namespace/topic

```

To unload all topics for a namespace and trigger reassignments:

```shell

pulsar-admin namespaces unload tenant/namespace

```

### Split namespace bundles

Since the load for the topics in a bundle might change over time, or predicting upfront might just be hard, brokers can split bundles into two. The new smaller bundles can be reassigned to different brokers.

The splitting happens based on some tunable thresholds. Any existing bundle that exceeds any of the threshold is a candidate to be split. By default the newly split bundles are also immediately offloaded to other brokers, to facilitate the traffic distribution.

```properties

# enable/disable namespace bundle auto split
loadBalancerAutoBundleSplitEnabled=true

# enable/disable automatic unloading of split bundles
loadBalancerAutoUnloadSplitBundlesEnabled=true

# maximum topics in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxTopics=1000

# maximum sessions (producers + consumers) in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxSessions=1000

# maximum msgRate (in + out) in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxMsgRate=30000

# maximum bandwidth (in + out) in a bundle, otherwise bundle split will be triggered
loadBalancerNamespaceBundleMaxBandwidthMbytes=100

# maximum number of bundles in a namespace (for auto-split)
loadBalancerNamespaceMaximumBundles=128

```

### Shed load automatically

The support for automatic load shedding is available in the load manager of Pulsar. This means that whenever the system recognizes a particular broker is overloaded, the system forces some traffic to be reassigned to less loaded brokers.

When a broker is identified as overloaded, the broker forces to "unload" a subset of the bundles, the
ones with higher traffic, that make up for the overload percentage.

For example, the default threshold is 85% and if a broker is over quota at 95% CPU usage, then the broker unloads the percent difference plus a 5% margin: `(95% - 85%) + 5% = 15%`.

Given the selection of bundles to offload is based on traffic (as a proxy measure for cpu, network
and memory), broker unloads bundles for at least 15% of traffic.

The automatic load shedding is enabled by default and you can disable the automatic load shedding with this setting:

```properties

# Enable/disable automatic bundle unloading for load-shedding
loadBalancerSheddingEnabled=true

```

Additional settings that apply to shedding:

```properties

# Load shedding interval. Broker periodically checks whether some traffic should be offload from
# some over-loaded broker to other under-loaded brokers
loadBalancerSheddingIntervalMinutes=1

# Prevent the same topics to be shed and moved to other brokers more that once within this timeframe
loadBalancerSheddingGracePeriodMinutes=30

```

#### Broker overload thresholds

The determinations of when a broker is overloaded is based on threshold of CPU, network and memory usage. Whenever either of those metrics reaches the threshold, the system triggers the shedding (if enabled).

By default, overload threshold is set at 85%:

```properties

# Usage threshold to determine a broker as over-loaded
loadBalancerBrokerOverloadedThresholdPercentage=85

```

Pulsar gathers the usage stats from the system metrics.

In case of network utilization, in some cases the network interface speed that Linux reports is
not correct and needs to be manually overridden. This is the case in AWS EC2 instances with 1Gbps
NIC speed for which the OS reports 10Gbps speed.

Because of the incorrect max speed, the Pulsar load manager might think the broker has not reached the NIC capacity, while in fact the broker already uses all the bandwidth and the traffic is slowed down.

You can use the following setting to correct the max NIC speed:

```properties

# Override the auto-detection of the network interfaces max speed.
# This option is useful in some environments (eg: EC2 VMs) where the max speed
# reported by Linux is not reflecting the real bandwidth available to the broker.
# Since the network usage is employed by the load manager to decide when a broker
# is overloaded, it is important to make sure the info is correct or override it
# with the right value here. The configured value can be a double (eg: 0.8) and that
# can be used to trigger load-shedding even before hitting on NIC limits.
loadBalancerOverrideBrokerNicSpeedGbps=

```

When the value is empty, Pulsar uses the value that the OS reports.

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
id: administration-proxy
title: Pulsar proxy
sidebar_label: "Pulsar proxy"
original_id: administration-proxy
---

Pulsar proxy is an optional gateway. Pulsar proxy is used when direction connections between clients and Pulsar brokers are either infeasible or undesirable. For example, when you run Pulsar in a cloud environment or on [Kubernetes](https://kubernetes.io) or an analogous platform, you can run Pulsar proxy.

## Configure the proxy

Before using the proxy, you need to configure it with the brokers addresses in the cluster. You can configure the proxy to connect directly to service discovery, or specify a broker URL in the configuration.

### Use service discovery

Pulsar uses [ZooKeeper](https://zookeeper.apache.org) for service discovery. To connect the proxy to ZooKeeper, specify the following in `conf/proxy.conf`.

```properties

zookeeperServers=zk-0,zk-1,zk-2
configurationStoreServers=zk-0:2184,zk-remote:2184

```

> To use service discovery, you need to open the network ACLs, so the proxy can connects to the ZooKeeper nodes through the ZooKeeper client port (port `2181`) and the configuration store client port (port `2184`).
> However, it is not secure to use service discovery. Because if the network ACL is open, when someone compromises a proxy, they have full access to ZooKeeper.
### Use broker URLs

It is more secure to specify a URL to connect to the brokers.

Proxy authorization requires access to ZooKeeper, so if you use these broker URLs to connect to the brokers, you need to disable authorization at the Proxy level. Brokers still authorize requests after the proxy forwards them.

You can configure the broker URLs in `conf/proxy.conf` as follows.

```properties

brokerServiceURL=pulsar://brokers.example.com:6650
brokerWebServiceURL=http://brokers.example.com:8080
functionWorkerWebServiceURL=http://function-workers.example.com:8080

```

If you use TLS, configure the broker URLs in the following way:

```properties

brokerServiceURLTLS=pulsar+ssl://brokers.example.com:6651
brokerWebServiceURLTLS=https://brokers.example.com:8443
functionWorkerWebServiceURL=https://function-workers.example.com:8443

```

The hostname in the URLs provided should be a DNS entry which points to multiple brokers or a virtual IP address, which is backed by multiple broker IP addresses, so that the proxy does not lose connectivity to Pulsar cluster if a single broker becomes unavailable.

The ports to connect to the brokers (6650 and 8080, or in the case of TLS, 6651 and 8443) should be open in the network ACLs.

Note that if you do not use functions, you do not need to configure `functionWorkerWebServiceURL`.

## Start the proxy

To start the proxy:

```bash

$ cd /path/to/pulsar/directory
$ bin/pulsar proxy

```

> You can run multiple instances of the Pulsar proxy in a cluster.
## Stop the proxy

Pulsar proxy runs in the foreground by default. To stop the proxy, simply stop the process in which the proxy is running.

## Proxy frontends

You can run Pulsar proxy behind some kind of load-distributing frontend, such as an [HAProxy](https://www.digitalocean.com/community/tutorials/an-introduction-to-haproxy-and-load-balancing-concepts) load balancer.

## Use Pulsar clients with the proxy

Once your Pulsar proxy is up and running, preferably behind a load-distributing [frontend](#proxy-frontends), clients can connect to the proxy via whichever address that the frontend uses. If the address is the DNS address `pulsar.cluster.default`, for example, the connection URL for clients is `pulsar://pulsar.cluster.default:6650`.

For more information on Proxy configuration, refer to [Pulsar proxy](reference-configuration.md#pulsar-proxy).
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
id: administration-pulsar-manager
title: Pulsar Manager
sidebar_label: "Pulsar Manager"
original_id: administration-pulsar-manager
---

Pulsar Manager is a web-based GUI management and monitoring tool that helps administrators and users manage and monitor tenants, namespaces, topics, subscriptions, brokers, clusters, and so on, and supports dynamic configuration of multiple environments.

:::note

If you monitor your current stats with [Pulsar dashboard](administration-dashboard), you can try to use Pulsar Manager instead. Pulsar dashboard is deprecated.

:::

## Install

The easiest way to use the Pulsar Manager is to run it inside a [Docker](https://www.docker.com/products/docker) container.

```shell

docker pull apachepulsar/pulsar-manager:v0.2.0
docker run -it \
-p 9527:9527 -p 7750:7750 \
-e SPRING_CONFIGURATION_FILE=/pulsar-manager/pulsar-manager/application.properties \
apachepulsar/pulsar-manager:v0.2.0

```

* `SPRING_CONFIGURATION_FILE`: Default configuration file for spring.

### Set administrator account and password

```shell

CSRF_TOKEN=$(curl http://localhost:7750/pulsar-manager/csrf-token)
curl \
-H 'X-XSRF-TOKEN: $CSRF_TOKEN' \
-H 'Cookie: XSRF-TOKEN=$CSRF_TOKEN;' \
-H "Content-Type: application/json" \
-X PUT http://localhost:7750/pulsar-manager/users/superuser \
-d '{"name": "admin", "password": "apachepulsar", "description": "test", "email": "username@test.org"}'

```

You can find the docker image in the [Docker Hub](https://github.com/apache/pulsar-manager/tree/master/docker) directory and build an image from the source code as well:

```
git clone https://github.com/apache/pulsar-manager
cd pulsar-manager/front-end
npm install --save
npm run build:prod
cd ..
./gradlew build -x test
cd ..
docker build -f docker/Dockerfile --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` --build-arg VCS_REF=`latest` --build-arg VERSION=`latest` -t apachepulsar/pulsar-manager .
```

### Use custom databases

If you have a large amount of data, you can use a custom database. The following is an example of PostgreSQL.

1. Initialize database and table structures using the [file](https://github.com/apache/pulsar-manager/tree/master/src/main/resources/META-INF/sql/postgresql-schema.sql).

2. Modify the [configuration file](https://github.com/apache/pulsar-manager/blob/master/src/main/resources/application.properties) and add PostgreSQL configuration.

```
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://127.0.0.1:5432/pulsar_manager
spring.datasource.username=postgres
spring.datasource.password=postgres
```

3. Compile to generate a new executable jar package.

```
./gradlew build -x test
```

### Enable JWT authentication

If you want to turn on JWT authentication, configure the following parameters:

* `backend.jwt.token`: token for the superuser. You need to configure this parameter during cluster initialization.
* `jwt.broker.token.mode`: multiple modes of generating token, including PUBLIC, PRIVATE, and SECRET.
* `jwt.broker.public.key`: configure this option if you use the PUBLIC mode.
* `jwt.broker.private.key`: configure this option if you use the PRIVATE mode.
* `jwt.broker.secret.key`: configure this option if you use the SECRET mode.

For more information, see [Token Authentication Admin of Pulsar](http://pulsar.apache.org/docs/en/security-token-admin/).


If you want to enable JWT authentication, use one of the following methods.


* Method 1: use command-line tool

```
wget https://dist.apache.org/repos/dist/release/pulsar/pulsar-manager/apache-pulsar-manager-0.2.0/apache-pulsar-manager-0.2.0-bin.tar.gz
tar -zxvf apache-pulsar-manager-0.2.0-bin.tar.gz
cd pulsar-manager
tar -zxvf pulsar-manager.tar
cd pulsar-manager
cp -r ../dist ui
./bin/pulsar-manager --redirect.host=http://localhost --redirect.port=9527 insert.stats.interval=600000 --backend.jwt.token=token --jwt.broker.token.mode=PRIVATE --jwt.broker.private.key=file:///path/broker-private.key --jwt.broker.public.key=file:///path/broker-public.key
```

Firstly, [set the administrator account and password](#set-administrator-account-and-password)

Secondly, log in to Pulsar manager through http://localhost:7750/ui/index.html.

* Method 2: configure the application.properties file

```
backend.jwt.token=token
jwt.broker.token.mode=PRIVATE
jwt.broker.public.key=file:///path/broker-public.key
jwt.broker.private.key=file:///path/broker-private.key
or
jwt.broker.token.mode=SECRET
jwt.broker.secret.key=file:///path/broker-secret.key
```

* Method 3: use Docker and enable token authentication.

```
export JWT_TOKEN="your-token"
docker run -it -p 9527:9527 -p 7750:7750 -e REDIRECT_HOST=http://localhost -e REDIRECT_PORT=9527 -e DRIVER_CLASS_NAME=org.postgresql.Driver -e URL='jdbc:postgresql://127.0.0.1:5432/pulsar_manager' -e USERNAME=pulsar -e PASSWORD=pulsar -e LOG_LEVEL=DEBUG -e JWT_TOKEN=$JWT_TOKEN -v $PWD:/data apachepulsar/pulsar-manager:v0.2.0 /bin/sh
```

* `JWT_TOKEN`: the token of superuser configured for the broker. It is generated by the `bin/pulsar tokens create --secret-key` or `bin/pulsar tokens create --private-key` command.
* `REDIRECT_HOST`: the IP address of the front-end server.
* `REDIRECT_PORT`: the port of the front-end server.
* `DRIVER_CLASS_NAME`: the driver class name of the PostgreSQL database.
* `URL`: the JDBC URL of your PostgreSQL database, such as jdbc:postgresql://127.0.0.1:5432/pulsar_manager. The docker image automatically start a local instance of the PostgreSQL database.
* `USERNAME`: the username of PostgreSQL.
* `PASSWORD`: the password of PostgreSQL.
* `LOG_LEVEL`: the level of log.

* Method 4: use Docker and turn on **token authentication** and **token management** by private key and public key.

```
export JWT_TOKEN="your-token"
export PRIVATE_KEY="file:///pulsar-manager/secret/my-private.key"
export PUBLIC_KEY="file:///pulsar-manager/secret/my-public.key"
docker run -it -p 9527:9527 -p 7750:7750 -e REDIRECT_HOST=http://localhost -e REDIRECT_PORT=9527 -e DRIVER_CLASS_NAME=org.postgresql.Driver -e URL='jdbc:postgresql://127.0.0.1:5432/pulsar_manager' -e USERNAME=pulsar -e PASSWORD=pulsar -e LOG_LEVEL=DEBUG -e JWT_TOKEN=$JWT_TOKEN -e PRIVATE_KEY=$PRIVATE_KEY -e PUBLIC_KEY=$PUBLIC_KEY -v $PWD:/data -v $PWD/secret:/pulsar-manager/secret apachepulsar/pulsar-manager:v0.2.0 /bin/sh
```

* `JWT_TOKEN`: the token of superuser configured for the broker. It is generated by the `bin/pulsar tokens create --private-key` command.
* `PRIVATE_KEY`: private key path mounted in container, generated by `bin/pulsar tokens create-key-pair` command.
* `PUBLIC_KEY`: public key path mounted in container, generated by `bin/pulsar tokens create-key-pair` command.
* `$PWD/secret`: the folder where the private key and public key generated by the `bin/pulsar tokens create-key-pair` command are placed locally
* `REDIRECT_HOST`: the IP address of the front-end server.
* `REDIRECT_PORT`: the port of the front-end server.
* `DRIVER_CLASS_NAME`: the driver class name of the PostgreSQL database.
* `URL`: the JDBC URL of your PostgreSQL database, such as jdbc:postgresql://127.0.0.1:5432/pulsar_manager. The docker image automatically start a local instance of the PostgreSQL database.
* `USERNAME`: the username of PostgreSQL.
* `PASSWORD`: the password of PostgreSQL.
* `LOG_LEVEL`: the level of log.

* Method 5: use Docker and turn on **token authentication** and **token management** by secret key.

```
export JWT_TOKEN="your-token"
export SECRET_KEY="file:///pulsar-manager/secret/my-secret.key"
docker run -it -p 9527:9527 -p 7750:7750 -e REDIRECT_HOST=http://localhost -e REDIRECT_PORT=9527 -e DRIVER_CLASS_NAME=org.postgresql.Driver -e URL='jdbc:postgresql://127.0.0.1:5432/pulsar_manager' -e USERNAME=pulsar -e PASSWORD=pulsar -e LOG_LEVEL=DEBUG -e JWT_TOKEN=$JWT_TOKEN -e SECRET_KEY=$SECRET_KEY -v $PWD:/data -v $PWD/secret:/pulsar-manager/secret apachepulsar/pulsar-manager:v0.2.0 /bin/sh
```

* `JWT_TOKEN`: the token of superuser configured for the broker. It is generated by the `bin/pulsar tokens create --secret-key` command.
* `SECRET_KEY`: secret key path mounted in container, generated by `bin/pulsar tokens create-secret-key` command.
* `$PWD/secret`: the folder where the secret key generated by the `bin/pulsar tokens create-secret-key` command are placed locally
* `REDIRECT_HOST`: the IP address of the front-end server.
* `REDIRECT_PORT`: the port of the front-end server.
* `DRIVER_CLASS_NAME`: the driver class name of the PostgreSQL database.
* `URL`: the JDBC URL of your PostgreSQL database, such as jdbc:postgresql://127.0.0.1:5432/pulsar_manager. The docker image automatically start a local instance of the PostgreSQL database.
* `USERNAME`: the username of PostgreSQL.
* `PASSWORD`: the password of PostgreSQL.
* `LOG_LEVEL`: the level of log.

* For more information about backend configurations, see [here](https://github.com/apache/pulsar-manager/blob/master/src/README).
* For more information about frontend configurations, see [here](https://github.com/apache/pulsar-manager/tree/master/front-end).

## Log in

[Set the administrator account and password](#set-administrator-account-and-password).

Visit http://localhost:9527 to log in.
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
id: administration-stats
title: Pulsar stats
sidebar_label: "Pulsar statistics"
original_id: administration-stats
---

## Partitioned topics

|Stat|Description|
|---|---|
|msgRateIn| The sum of publish rates of all local and replication publishers in messages per second.|
|msgThroughputIn| Same as msgRateIn but in bytes per second instead of messages per second.|
|msgRateOut| The sum of dispatch rates of all local and replication consumers in messages per second.|
|msgThroughputOut| Same as msgRateOut but in bytes per second instead of messages per second.|
|averageMsgSize| Average message size, in bytes, from this publisher within the last interval.|
|storageSize| The sum of storage size of the ledgers for this topic.|
|publishers| The list of all local publishers into the topic. Publishers can be anywhere from zero to thousands.|
|producerId| Internal identifier for this producer on this topic.|
|producerName| Internal identifier for this producer, generated by the client library.|
|address| IP address and source port for the connection of this producer.|
|connectedSince| Timestamp this producer is created or last reconnected.|
|subscriptions| The list of all local subscriptions to the topic.|
|my-subscription| The name of this subscription (client defined).|
|msgBacklog| The count of messages in backlog for this subscription.|
|type| This subscription type.|
|msgRateExpired| The rate at which messages are discarded instead of dispatched from this subscription due to TTL.|
|consumers| The list of connected consumers for this subscription.|
|consumerName| Internal identifier for this consumer, generated by the client library.|
|availablePermits| The number of messages this consumer has space for in the listen queue of client library. A value of 0 means the queue of client library is full and receive() is not being called. A nonzero value means this consumer is ready to be dispatched messages.|
|replication| This section gives the stats for cross-colo replication of this topic.|
|replicationBacklog| The outbound replication backlog in messages.|
|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 publisher connection of remote cluster to this broker. |
|inboundConnectedSince| The TCP connection being used to publish messages to the remote cluster. If no local publishers are connected, this connection is automatically closed after a minute.|


## Topics

|Stat|Description|
|---|---|
|entriesAddedCounter| Messages published since this broker loads this topic.|
|numberOfEntries| Total number of messages being tracked.|
|totalSize| Total storage size in bytes of all messages.|
|currentLedgerEntries| Count of messages written to the ledger currently open for writing.|
|currentLedgerSize| Size in bytes of messages written to ledger currently open for writing.|
|lastLedgerCreatedTimestamp| Time when last ledger is created.|
|lastLedgerCreationFailureTimestamp| Time when last ledger is failed.|
|waitingCursorsCount| How many cursors are caught up and waiting for a new message to be published.|
|pendingAddEntriesCount| How many messages have (asynchronous) write requests you are waiting on completion.|
|lastConfirmedEntry| The ledgerid:entryid of the last message successfully written. If the entryid is -1, then the ledger is opened or is being currently opened but has no entries written yet.|
|state| The state of the cursor ledger. Open means you have a cursor ledger for saving updates of the markDeletePosition.|
|ledgers| The ordered list of all ledgers for this topic holding its messages.|
|cursors| The list of all cursors on this topic. Every subscription you saw in the topic stats has one.|
|markDeletePosition| The ack position: the last message the subscriber acknowledges receiving.|
|readPosition| The latest position of subscriber for reading message.|
|waitingReadOp| This is true when the subscription reads the latest message that is published to the topic and waits on new messages to be published.|
|pendingReadOps| The counter for how many outstanding read requests to the BookKeepers you have in progress.|
|messagesConsumedCounter| Number of messages this cursor acks since this broker loads this topic.|
|cursorLedger| The ledger used to persistently store the current markDeletePosition.|
|cursorLedgerLastEntry| The last entryid used to persistently store the current markDeletePosition.|
|individuallyDeletedMessages| If Acks are done out of order, shows the ranges of messages Acked between the markDeletePosition and the read-position.|
|lastLedgerSwitchTimestamp| The last time the cursor ledger is rolled over.|
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
---
id: administration-upgrade
title: Upgrade Guide
sidebar_label: "Upgrade"
original_id: administration-upgrade
---

## Upgrade guidelines

Apache Pulsar is comprised of multiple components, ZooKeeper, bookies, and brokers. These components are either stateful or stateless. You do not have to upgrade ZooKeeper nodes unless you have special requirement. While you upgrade, you need to pay attention to bookies (stateful), brokers and proxies (stateless).

The following are some guidelines on upgrading a Pulsar cluster. Read the guidelines before upgrading.

- Backup all your configuration files before upgrading.
- Read guide entirely, make a plan, and then execute the plan. When you make upgrade plan, you need to take your specific requirements and environment into consideration.
- Pay attention to the upgrading order of components. In general, you do not need to upgrade your ZooKeeper or configuration store cluster (the global ZooKeeper cluster). You need to upgrade bookies first, and then upgrade brokers, proxies, and your clients.
- If `autorecovery` is enabled, you need to disable `autorecovery` in the upgrade process, and re-enable it after completing the process.
- Read the release notes carefully for each release. Release notes contain features, configuration changes that might impact your upgrade.
- Upgrade a small subset of nodes of each type to canary test the new version before upgrading all nodes of that type in the cluster. When you have upgraded the canary nodes, run for a while to ensure that they work correctly.
- Upgrade one data center to verify new version before upgrading all data centers if your cluster runs in multi-cluster replicated mode.

> Note: Currently, Apache Pulsar is compatible between versions.
## Upgrade sequence

To upgrade an Apache Pulsar cluster, follow the upgrade sequence.

1. Upgrade ZooKeeper (optional)
- Canary test: test an upgraded version in one or a small set of ZooKeeper nodes.
- Rolling upgrade: rollout the upgraded version to all ZooKeeper servers incrementally, one at a time. Monitor your dashboard during the whole rolling upgrade process.
2. Upgrade bookies
- Canary test: test an upgraded version in one or a small set of bookies.
- Rolling upgrade:
- a. Disable `autorecovery` with the following command.

```shell

bin/bookkeeper shell autorecovery -disable

```


- b. Rollout the upgraded version to all bookies in the cluster after you determine that a version is safe after canary.
- c. After you upgrade all bookies, re-enable `autorecovery` with the following command.

```shell
bin/bookkeeper shell autorecovery -enable
```

3. Upgrade brokers
- Canary test: test an upgraded version in one or a small set of brokers.
- Rolling upgrade: rollout the upgraded version to all brokers in the cluster after you determine that a version is safe after canary.
4. Upgrade proxies
- Canary test: test an upgraded version in one or a small set of proxies.
- Rolling upgrade: rollout the upgraded version to all proxies in the cluster after you determine that a version is safe after canary.

## Upgrade ZooKeeper (optional)
While you upgrade ZooKeeper servers, you can do canary test first, and then upgrade all ZooKeeper servers in the cluster.

### Canary test

You can test an upgraded version in one of ZooKeeper servers before upgrading all ZooKeeper servers in your cluster.

To upgrade ZooKeeper server to a new version, complete the following steps:

1. Stop a ZooKeeper server.
2. Upgrade the binary and configuration files.
3. Start the ZooKeeper server with the new binary files.
4. Use `pulsar zookeeper-shell` to connect to the newly upgraded ZooKeeper server and run a few commands to verify if it works as expected.
5. Run the ZooKeeper server for a few days, observe and make sure the ZooKeeper cluster runs well.

#### Canary rollback

If issues occur during canary test, you can shut down the problematic ZooKeeper node, revert the binary and configuration, and restart the ZooKeeper with the reverted binary.

### Upgrade all ZooKeeper servers

After canary test to upgrade one ZooKeeper in your cluster, you can upgrade all ZooKeeper servers in your cluster.

You can upgrade all ZooKeeper servers one by one by following steps in canary test.

## Upgrade bookies

While you upgrade bookies, you can do canary test first, and then upgrade all bookies in the cluster.
For more details, you can read Apache BookKeeper [Upgrade guide](http://bookkeeper.apache.org/docs/latest/admin/upgrade).

### Canary test

You can test an upgraded version in one or a small set of bookies before upgrading all bookies in your cluster.

To upgrade bookie to a new version, complete the following steps:

1. Stop a bookie.
2. Upgrade the binary and configuration files.
3. Start the bookie in `ReadOnly` mode to verify if the bookie of this new version runs well for read workload.

```shell
bin/pulsar bookie --readOnly
```

4. When the bookie runs successfully in `ReadOnly` mode, stop the bookie and restart it in `Write/Read` mode.

```shell
bin/pulsar bookie
```

5. Observe and make sure the cluster serves both write and read traffic.

#### Canary rollback

If issues occur during the canary test, you can shut down the problematic bookie node. Other bookies in the cluster replaces this problematic bookie node with autorecovery.

### Upgrade all bookies

After canary test to upgrade some bookies in your cluster, you can upgrade all bookies in your cluster.

Before upgrading, you have to decide whether to upgrade the whole cluster at once, including downtime and rolling upgrade scenarios.

In a rolling upgrade scenario, upgrade one bookie at a time. In a downtime upgrade scenario, shut down the entire cluster, upgrade each bookie, and then start the cluster.

While you upgrade in both scenarios, the procedure is the same for each bookie.

1. Stop the bookie.
2. Upgrade the software (either new binary or new configuration files).
2. Start the bookie.

> **Advanced operations**
> When you upgrade a large BookKeeper cluster in a rolling upgrade scenario, upgrading one bookie at a time is slow. If you configure rack-aware or region-aware placement policy, you can upgrade bookies rack by rack or region by region, which speeds up the whole upgrade process.

## Upgrade brokers and proxies

The upgrade procedure for brokers and proxies is the same. Brokers and proxies are `stateless`, so upgrading the two services is easy.

### Canary test

You can test an upgraded version in one or a small set of nodes before upgrading all nodes in your cluster.

To upgrade to a new version, complete the following steps:

1. Stop a broker (or proxy).
2. Upgrade the binary and configuration file.
3. Start a broker (or proxy).

#### Canary rollback

If issues occur during canary test, you can shut down the problematic broker (or proxy) node. Revert to the old version and restart the broker (or proxy).

### Upgrade all brokers or proxies

After canary test to upgrade some brokers or proxies in your cluster, you can upgrade all brokers or proxies in your cluster.

Before upgrading, you have to decide whether to upgrade the whole cluster at once, including downtime and rolling upgrade scenarios.

In a rolling upgrade scenario, you can upgrade one broker or one proxy at a time if the size of the cluster is small. If your cluster is large, you can upgrade brokers or proxies in batches. When you upgrade a batch of brokers or proxies, make sure the remaining brokers and proxies in the cluster have enough capacity to handle the traffic during upgrade.

In a downtime upgrade scenario, shut down the entire cluster, upgrade each broker or proxy, and then start the cluster.

While you upgrade in both scenarios, the procedure is the same for each broker or proxy.

1. Stop the broker or proxy.
2. Upgrade the software (either new binary or new configuration files).
3. Start the broker or proxy.
Loading