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

PIP 110: Support Topic metadata - PART-1 create topic with properties #12818

Merged
merged 28 commits into from
Jan 25, 2022

Conversation

Technoboy-
Copy link
Contributor

@Technoboy- Technoboy- commented Nov 15, 2021

Fixes #12629

Motivation

The original discussion mail :
https://lists.apache.org/thread/m9dkhq1fs6stsdwh78h84fsl5hs5v67f

Introduce the ability to store metadata about topics.

This would be very useful as with metadata you could add labels and other
pieces of information that would allow defining the purpose of a topic,
custom application-level properties.
This feature will allow application-level diagnostic tools and maintenance
tools to not need external databases to store such metadata.

Imagine that we could add a simple key value map (String keys and String
values) to the topic.
These metadata could be set during topic creation and also updated.

Modification

  • Add two new rest API reduce compatibility issue :
    @path("/{property}/{cluster}/{namespace}/{topic}/partitions/properties")
    @path("/{tenant}/{cluster}/{namespace}/{topic}/properties")

  • Add below new methods in Topics.java :
    createPartitionedTopic(String topic, int numPartitions, Map<String, String> properties);
    createPartitionedTopicAsync(String topic, int numPartitions, Map<String, String> properties);
    createNonPartitionedTopic(String topic, Map<String, String> properties);
    createNonPartitionedTopicAsync(String topic, Map<String, String> properties);

Documentation

  • [ x ] no-need-doc

@github-actions github-actions bot added the doc-not-needed Your PR changes do not impact docs label Nov 15, 2021
@codelipenghui codelipenghui added this to the 2.10.0 milestone Jan 18, 2022
Copy link
Contributor

@codelipenghui codelipenghui left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a way to get the properties? Looks like the PR just supports set properties, but is not able to get the properties.

@Technoboy-
Copy link
Contributor Author

Do we have a way to get the properties? Looks like the PR just supports set properties, but is not able to get the properties.

These new properties are put in PartitionedTopicMetadata. So we can get it from getPartitionedMetadata

@Technoboy- Technoboy- changed the title PIP 110: Support Topic metadata PIP 110: Support Topic metadata - PART-1 create topic with properties Jan 18, 2022
@ApiParam(value = "The number of partitions for the topic",
required = true, type = "int", defaultValue = "0")
int numPartitions,
@ApiParam(value = "The metadata for the topic",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a breaking change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For there exists one param in this method before, we can't add a new param to this method because the body value only supports one param.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codelipenghui It looks like not. I ran the following command in my local env:

curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d 3

We can see the partitions number was recognized correctly.

image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also tried -d '{"partitions":"3","properties":{"k1":"v1","k2":"v2"}}' and it works well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have tried curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '{"partitions":"3","properties":{"k1":"v1","k2":"v2"}}'

Got 400 at the broker side:

2022-01-19T18:41:56,584+0800 [pulsar-web-59-12] INFO  org.eclipse.jetty.server.RequestLog - 127.0.0.1 - - [19/Jan/2022:18:41:56 +0800] "PUT /admin/v2/persistent/public/default/xxx/partitions HTTP/1.1" 400 212 "-" "curl/7.77.0" 2

Got exception at the client-side

Cannot deserialize value of type `int` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]%

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we can't avoid breaking compatibility, we can add a new endpoint in v3 REST APIs

Copy link
Contributor

@BewareMyPower BewareMyPower Jan 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you compile the latest code? Here are the test input from my local env:

$ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '{"partitions":"3","properties":{"k1":"v1","k2":"v2"}}'
$ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions                                                                                                      
{"partitions":3,"properties":{"k1":"v1","k2":"v2"}}                                                                                                                                                                                                         $ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X DELETE
$ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '{"partitions":"3","properties":{"k3":"v3"}}'          
$ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions                                                                                            
{"partitions":3,"properties":{"k3":"v3"}}

If you used the original code, since the body must be an integer, the body {"partitions":"3","properties":{"k1":"v1","k2":"v2"}} cannot be recognized.

$ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '3'                 
$ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions                                                                                                      
{"partitions":3}                                                                                                                                                                                                                                             $ curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '{"partitions":"3"}'
Cannot deserialize value of type `int` from Object value (token `JsonToken.START_OBJECT`)
 at [Source: (org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream); line: 1, column: 1]

But I don't think it breaks the backward compatibility. This PR makes the REST API available for more input.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you used the original code, since the body must be an integer, the body {"partitions":"3","properties":{"k1":"v1","k2":"v2"}} cannot be recognized.

Yes, this is my test case, use the new Pulsar Admin version to point to the old broker.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. I think there is no good way for this compatibility. We can only guarantee New Broker is compatible with Old Client

@BewareMyPower
Copy link
Contributor

BTW, could you check #12629 (comment)? I have the same concern that for a partitioned topic, what's the behavior when an individual partition's properties was set?

For example, I ran following commands:

curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '{"partitions":"3","properties":{"k1":"v1","k2":"v2"}}'
curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx-partition-0 -X DELETE
curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx-partition-0 -X PUT -H 'Content-Type: application/json' -d '{"k3":"v3"}'
  1. Create a partitioned topic xxx with 3 partitions and properties k1 -> v1, k2 -> v2.
  2. Delete the 1st partition (xxx-partition-0).
  3. Create the 1st partition with properties k3 -> v3.

The 3rd step works well but I think it should be prevented. /cc @eolivelli Is it what you concerned?

@Technoboy-
Copy link
Contributor Author

BTW, could you check #12629 (comment)? I have the same concern that for a partitioned topic, what's the behavior when an individual partition's properties was set?

For example, I ran following commands:

curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx/partitions -X PUT -H 'Content-Type: application/json' -d '{"partitions":"3","properties":{"k1":"v1","k2":"v2"}}'
curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx-partition-0 -X DELETE
curl -L http://localhost:8080/admin/v2/persistent/public/default/xxx-partition-0 -X PUT -H 'Content-Type: application/json' -d '{"k3":"v3"}'
  1. Create a partitioned topic xxx with 3 partitions and properties k1 -> v1, k2 -> v2.
  2. Delete the 1st partition (xxx-partition-0).
  3. Create the 1st partition with properties k3 -> v3.

The 3rd step works well but I think it should be prevented. /cc @eolivelli Is it what you concerned?

Ok。

@Path("/persistent")
@Produces(MediaType.APPLICATION_JSON)
@Api(value = "/persistent", description = "Persistent topic admin apis", tags = "persistent topic")
public class PersistentTopics extends PersistentTopicsBase {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this new package?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can see the discussion in #12818 (comment).

Because when new PulsarAdmin sends the request to old broker, the old broker cannot recognize the JSON body like {"partitions":3}. /cc @codelipenghui

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we have changed the method from createPartitionedTopic(partitions) to createPartitionedTopic(partitionedTopicMetadata)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes sense to me.
so when you use the "new" pulsar-admin (2.10) with an old broker
how can we deal with compatibility ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because we have changed the method from createPartitionedTopic(partitions) to createPartitionedTopic(partitionedTopicMetadata)

It should be possible to handle that in a backwards compatible way without breaking the API. It's better to revert the addition of a new API version and instead revisit the solution in a proper way.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my understanding in this patch was that we are using the v3 endpoint only in case of passing the "properties" and to use v2 in the other cases

it looks like it is kind of a simple but in the logic to choose the endpoint

Copy link
Contributor

@eolivelli eolivelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please answer to my latest questions/requests.
Basically I would like to add come comments in PulsarAdmin "topicPath" method in order to say why and when we are using V3 API.

Apart from that I am +1

@codelipenghui codelipenghui merged commit 10036d5 into apache:master Jan 25, 2022
codelipenghui pushed a commit that referenced this pull request Jun 8, 2022
### Motivation

As #12818 has supported creating topics with metadata, this patch is adding a `get` API to support getting topic properties.
codelipenghui pushed a commit that referenced this pull request Jun 12, 2022
As #12818 has supported creating topics with metadata, this patch is adding a `get` API to support getting topic properties.

(cherry picked from commit 1ebe4ee)
nicoloboschi pushed a commit to datastax/pulsar that referenced this pull request Jun 13, 2022
As apache#12818 has supported creating topics with metadata, this patch is adding a `get` API to support getting topic properties.

(cherry picked from commit 1ebe4ee)
(cherry picked from commit 6648f99)
@Technoboy- Technoboy- deleted the topic-metadata-1 branch August 10, 2022 05:51
@syhily
Copy link

syhily commented Feb 27, 2023

Hi there. Since the metadata can be created on topic level. Any plan for adding metadata update logic for topic?

@Technoboy-
Copy link
Contributor Author

Hi there. Since the metadata can be created on topic level. Any plan for adding metadata update logic for topic?

#17238

RobertIndie pushed a commit to apache/pulsar-client-go that referenced this pull request Jun 12, 2024
### Motivation

To keep consistent with the [Java client](apache/pulsar#12818).


### Modifications

- Add admin topic api CreateWithProperties
-  Add admin topic api GetProperties
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
doc-not-needed Your PR changes do not impact docs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PIP 110: Topic metadata
9 participants