apache / pulsar-client-go

Apache Pulsar Go Client Library
https://pulsar.apache.org/
Apache License 2.0
660 stars 336 forks source link

Tracking issue for merging pulsar-admin-go #1075

Open tisonkun opened 1 year ago

tisonkun commented 1 year ago

Background

Subtasks

tisonkun commented 1 year ago

@flowchartsman I outline the subtasks above and will start roughly adding source code the next week. You may propose the refactor ideas and I can help in review.

cc @RobertIndie @shibd @nodece @wolfstudy

flowchartsman commented 1 year ago

Thanks @tisonkun! We might want to open the issue for discussion first before we issue PRs, since the current API and mine are fairly different, and it might help to avoid duplicated effort, but I'm game to do it however you like.I can convert my draft PR to a regular one first?

For those interested, I have a refactoring issue and accompanying PR in place for pulsar-admin-go that removes most of the package divisions, unifying the types and API calls into a single root package as well as refactoring http client and auth code to into internal, to avoid cluttering the namespace and exposing auth via a functional API. This avoids the necessity of importing multiple pkg packages to perform any one action, and avoids exposing any internals to the user that they will have no use for. Many of these changes will apply to a merger in pulsar-client-go.

The PR also adds package-level error interfaces along with helper methods to distinguish missing/not found entities from actual errors, as well as "expected" errors which conform to the admin API (i.e. with a reason) versus those errors that represent more exceptional circumstances. The internal error types are not exposed to the user; instead the interfaces can be checked against an error value using the standard library errors.As.

Notes on merging

Once integrated, one way to call the adminAPI might be directly from the Client type, like so:

        client, err := pulsar.NewClient(ClientOptions{
        URL:                   serviceURLTLS,
        TLSTrustCertsFilePath: caCertsPath,
                TLSValidateHostname:   true,
        Authentication: NewAuthenticationToken(string(token)),
    })
        err := client.Admin.Functions().CreateFuncWithURL(funcPkgURL, &pulsar.FunctionConfig{
        Output:     funcResults,
        LogTopic:   funcLog,
        Tenant:     funcTenant,
        Namespace:  funcNamespace,
        Name:       funcName,
        Inputs:     []string{funcInput},
        Runtime:    "GO",
        }
        if err != nil {
                // handle error
        }

Note the use of Functions() as a function which returns ~a particular API execution type~ a runner for the /v3/functions API. This could just as easily be replaced with a field on the Admin type.

tisonkun commented 1 year ago

Thanks for your feedback and participation @flowchartsman!

I've submitted a PR https://github.com/apache/pulsar-client-go/pull/1077 for roughly adding the sources of pulsar-admin-go, so that we have a baseline to improve and the downstream projects can first migrate to that hash for updating module/pkg path, and later catch up any refactors.

Your refactoring suggestions can be applied onto that patch.

package-level error interfaces along with helper methods

I like this.

exported Admin field

As we discussed on Slack, perhaps a parallel interface design for client API and admin API can be better. This is the design of Java APIs and it reflects that admin APIs (control panel) are at the same level of client API (data panel) - client APIs don't "own" admin APIs. Also, this can make the auth model clear - generally, users configure less permission for client APIs while admin APIs requires high trust level.

Because pulsar-client-go already handles (most) auth plugins natively, the functional auth API I designed for my PR would no longer be necessary, and authentication would come from the auth settings specified in pulsar.ClientConfig

This is the right direction. We will factor out shared/common configs and the auth package. But how to reduce the impact for current users is a point that needs a second consideration.

exercise most if not all endpoints using an actual pulsar container

This is cool! We definitely need it.