Git Product home page Git Product logo

azure-amqp-common-go's Introduction

Azure AMQP Common

Go Report Card godoc Build Status

This project contains reusable components for AMQP based services like Event Hub and Service Bus. You will find abstractions over authentication, claims-based security, connection string parsing and RPC for AMQP.

If you are looking for the Azure Event Hub library for go, you can find it here.

If you are looking for the Azure Service Bus library for go, you can find it here.

Install with Go modules

If you want to use stable versions of the library, please use Go modules.

NOTE: versions prior to 3.0.0 depend on pack.ag/amqp which is no longer maintained. Any new code should not use versions prior to 3.0.0.

Using go get targeting version 4.x.x

go get github.com/Azure/azure-amqp-common-go/v4

Using go get targeting version 3.x.x

go get github.com/Azure/azure-amqp-common-go/v3

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.microsoft.com.

When you submit a pull request, a CLA-bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., label, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

License

MIT, see LICENSE.

Contribute

See CONTRIBUTING.md.

azure-amqp-common-go's People

Contributors

akhilerm avatar bvwells avatar devigned avatar gavinfish avatar jhendrixmsft avatar jjcollinge avatar marstr avatar microsoft-github-policy-service[bot] avatar microsoftopensource avatar msftgits avatar richardpark-msft avatar serbrech avatar smuthusa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

azure-amqp-common-go's Issues

support for passing managed identity client id

When Azure VM is assigned more than one managed identity, the Azure AD expects the client id to be used for generating an auth token. Currently, azure-amqp-common-go is not considering the clientID when using MSI authentication.

Expected Behavior

managed identity based authentication should consider the ClientId when not empty

Actual Behavior

Environment

  • Version of Library: 2.1.0

Automatically add server-timeout property in `rpc` package

Desired Behavior

When calling rpc.RPC or rpc.RetryableRPC, I've been adding the "server-timeout" application property whenever the context of my operation has a deadline set. You can see an example here:

if deadline, ok := ctx.Deadline(); ok {
		msg.ApplicationProperties["server-timeout"] = uint(time.Until(deadline) / time.Millisecond)
	}

I believe that this is useful enough that it should become the behavior of all RPCs from this package.

Environment

  • OS: Mac OS 10.14
  • Go version: go1.11.1 darwin/amd64
  • Version of Library: master

Failed to start EPH for ... : link detached, reason: *Error{Condition: amqp:unauthorized-access, Description: Unauthorized access. 'Listen' claim(s) are required to perform this operation. Resource:

Hi ,

I am using aad.NewJWTProvider() method to get token to access data from Azure Event hub , instead of using aad.JWTProviderWithEnvironmentVars() in aad.NewJWTProvider(aad.JWTProviderWithEnvironmentVars()) I have created my own method in which I am assigning config.tenantID , client ID and client secret directly instead of assigning it from environment variables , below is the method.

func SetJWTProvider() aad.JWTProviderOption {
return func(config *aad.TokenProviderConfiguration) error {
config.TenantID = "e91f4e68-e9aa-45fd-b665-f2ab1e5739fb"
config.ClientID = "71c2a438-a7ee-442b-9a6f-8c8063918ecc"
config.ClientSecret = ".33lMCgfAAsDFDxo_f6r4A]kzaXnmfg@"
// config.CertificatePath = os.Getenv("AZURE_CERTIFICATE_PATH")
// config.CertificatePassword = os.Getenv("AZURE_CERTIFICATE_PASSWORD")

	if config.Env == nil {
		env, err := azureEnvFromEnvironment()
		if err != nil {
			return err
		}
		config.Env = env
	}
	return nil
}

}
while using this I am getting below error , it seems that I am not able to authorize my request to pull data from Azure event hub.

Failed to start EPH for Event hub i***** : link detached, reason: *Error{Condition: amqp:unauthorized-access, Description: Unauthorized access. 'Listen' claim(s) are required to perform this operation. Resource: '*****'. TrackingId:8****_G7, SystemTracker:gateway5, Timestamp:2019-11-08T09:27:19, Info: map[]}

Unhandled i/o timeout error leads to infinite busy loop in startResponseRouter() function

Expected Behavior

No busy loop, properly handling of network errors.

Actual Behavior

When i/o timeout error occurs, startResponseRouter() function enters busy loop here:

res, err := l.receiver.Receive(context.Background())

// You'll see this when the link is shutting down (either
// service-initiated via 'detach' or a user-initiated shutdown)
if isClosedError(err) {
    l.broadcastError(err)
    break
}

// I don't believe this should happen. The JS version of this same code
// ignores errors as well since responses should always be correlated
// to actual send requests. So this is just here for completeness.
if res == nil {
    continue
}

Environment

  • OS: Ubuntu 20.04
  • Go version: 17.1
  • Version of Library: 3.2.1

go get -u github.com/Azure/azure-amqp-common-go/... fails

Expected Behavior

$ go get -u github.com/Azure/azure-amqp-common-go/... should run without failing.

Actual Behavior

It outputs this error message:

# github.com/Azure/azure-amqp-common-go/aad
../../src/github.com/Azure/azure-amqp-common-go/aad/jwt.go:203:44: cannot use token.ExpiresOn (type json.Number) as type string in argument to strconv.ParseInt
../../src/github.com/Azure/azure-amqp-common-go/aad/jwt.go:216:69: cannot use token.ExpiresOn (type json.Number) as type string in argument to auth.NewToken

Environment

  • OS: Debian GNU/Linux
  • Go version: go1.11rc2 linux/amd64
  • Version of Library: dead23a

doRPCWithRetry() string-izes errors that come back from the call

DoRPCWithRetry() doesn't return the actual response from the remote service, which results in clients having to do string matches against the returned error.

The base cause is that .Retryable() error itself is a string, and that's what DoRPCWithRetry uses for flow control in it's retry mechanism.

This can be fixed, but we probably want to take some care that we don't break any parts of the interface.

Protocol error negotiating CBS claim

Expected Behavior

The azure-amqp-common-go cbs.NegotiateClaim call successfully negotiates the CBS claim when connecting to an Azure IoT Hub.

Actual Behavior

With some of our hubs the cbs.NegotiateClaim call is erroring out with protocol error: received flow without next-incoming-id after session established. We are using chirpstack-network-server to connect to Azure IoT Hub. It is using azure-amqp-common-go v1.1.4 to connect.

The strange thing is the same code works with some of our hubs but not others. Is this a known issue that later versions of azure-amqp-common-go fix? Or is there some setting that needs to be configured in the IoT Hub to prevent this from happening?

Below is debug output from the underlying pack.ag/amqp package showing some TX/RX frames. It appears to receive a nil value for NextIncomingID which results in the error are seeing. I'm not familiar enough with AMQP to know if that is an error that would be caused by a server side issue, or if there would need to be some change on the client side code to fix this.

16:57:15.364382 TX: Begin{RemoteChannel: 0, NextOutgoingID: 0, IncomingWindow: 100, OutgoingWindow: 100, HandleMax: 4294967295, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.412592 TX: Begin{RemoteChannel: 0, NextOutgoingID: 0, IncomingWindow: 100, OutgoingWindow: 100, HandleMax: 4294967295, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.426561 RX: Begin{RemoteChannel: 0, NextOutgoingID: 1, IncomingWindow: 4294967295, OutgoingWindow: 100, HandleMax: 4294967295, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.426665 TX: Attach{Name: L-cTAXLOyxlAOfA6EurUVtCOQu5oCag-yjx6-hNfCT-7b837ef28BQ, Handle: 0, Role: Sender, SenderSettleMode: <nil>, ReceiverSettleMode: <nil>, Source: <nil>, Target: source{Address: $cbs, Durable: 0, ExpiryPolicy: , Timeout: 0, Dynamic: false, DynamicNodeProperties: map[], Capabilities: []}, Unsettled: map[], IncompleteUnsettled: false, InitialDeliveryCount: 0, MaxMessageSize: 0, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.480834 RX: Begin{RemoteChannel: 0, NextOutgoingID: 1, IncomingWindow: 5000, OutgoingWindow: 100, HandleMax: 255, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.480928 TX: Attach{Name: zmoI64EQc9nqHUQFt2bKT0stoh4leXB9_zVIREhtH46qsdjiomn986ls, Handle: 0, Role: Sender, SenderSettleMode: <nil>, ReceiverSettleMode: <nil>, Source: <nil>, Target: source{Address: $cbs, Durable: 0, ExpiryPolicy: , Timeout: 0, Dynamic: false, DynamicNodeProperties: map[], Capabilities: []}, Unsettled: map[], IncompleteUnsettled: false, InitialDeliveryCount: 0, MaxMessageSize: 0, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.490770 RX(Session): Attach{Name: L-cTAXLOyxlAOfA6EurUVtCOQu5oCag-yjx6-hNfCT-7b837ef28BQ, Handle: 0, Role: Receiver, SenderSettleMode: mixed, ReceiverSettleMode: first, Source: <nil>, Target: source{Address: $cbs, Durable: 0, ExpiryPolicy: session-end, Timeout: 0, Dynamic: false, DynamicNodeProperties: map[], Capabilities: []}, Unsettled: map[], IncompleteUnsettled: false, InitialDeliveryCount: 0, MaxMessageSize: 1048576, OfferedCapabilities: [], DesiredCapabilities: [], Properties: map[]}
16:57:15.490825 RX(Session): Flow{NextIncomingID: <nil>, IncomingWindow: 4294967295, NextOutgoingID: 0, OutgoingWindow: 100, Handle: 0, DeliveryCount: 0, LinkCredit: 50, Available: <nil>, Drain: false, Echo: false, Properties: map[]}

Environment

  • OS: Ubuntu 20.04.4
  • Go version: 1.19.2
  • Version of Library: 1.1.4

Connection String fails when key contains `=`

If the connection string contains a key with =, the parser fails with the error specified here:

return nil, errors.New("failed parsing connection string due to unmatched key value separated by '='")

Example:
Endpoint=sb://example.servicebus.windows.net/;SharedAccessKeyName=sas_key;SharedAccessKey=asdijwu/Tadkjwaidubnas=;EntityPath=example

add support for alpine images or scratch

Expected Behavior

When running in a base image that is scratch or -alpine I'd expect it to work

Actual Behavior

Always get the below error:

failed to configure AAD JWT provider: failed to refersh token: &{{{ 0 0 0 } 0xc4203889f0 {{https login.microsoftonline.com /72f988bf-86f1-xxxx-xxxx-2d7cd011db47 false } {https login.microsoftonline.com /72f988bf-xxxx-xxxx-91ab-2d7cd011db47/oauth2/authorize false api-version=1.0 } {https login.microsoftonline.com /72f988bf-xxxx-xxxx-91ab-2d7cd011db47/oauth2/token false api-version=1.0 } {https login.microsoftonline.com /72f988bf-xxxx-xxxx-xxxx-2d7cd011db47/oauth2/devicecode false api-version=1.0 }} 930fab59-xxxx-xxxx-xxxx-484114d560ea https://eventhubs.azure.net/ true 300000000000} 0xc4202caee0 0xc42028a8d0 [] 0}

Environment

  • OS: both alpine:3.7 and scratch
  • Go version: 1.12.5
  • Version of Library: 1.1.4

Token based authentication is causing very frequent refresh token generation activity on Azure Portal

Expected Behavior

Actual Behavior

I am using tokenprovider approach to created new eventhub object.
tokenProvider, err := aad.NewJWTProvider(aad.JWTProviderWithEnvironmentVars())
cred, err := storageLeaser.NewAADSASCredential( azurehubevent.SubscriptionID, azurehubevent.ResourceGroupName, storageAccountName, w.StorageBlobName, storageLeaser.AADSASCredentialWithEnvironmentVars())
leaserCheckpointer, err := storage.NewStorageLeaserCheckpointer(cred, storageAccountName, w.StorageBlobName, azureEnv)
// Starting New Connection processor, err := eph.New( ctx, eventhubconnstring, eventhubinstanceName, tokenProvider, leaserCheckpointer, leaserCheckpointer, eventProcessorHostOption...)
err = processor.Start(ctx)

I am able to connect to event hub and fetch activity logs out of it. But seems most of the logs are related to "Returns Storage Account SAS Token". This is due to the very frequent call going from my application to refresh token.

Is there any way to reduce the number of refresh token calls?

Note : I saw dotnet version have one parameter called tokenTimeToLive to specify how long token is valid.

Environment

  • OS: windows 10
  • Go version: 13.4
  • Version of Library: Latest

Receiving amqp: link closed while using the library

Expected Behavior

The client handles amqp related issues and reconnects.

Actual Behavior

While using eventhub v3.3.16, amqp v3.2.2, I'm occasionally encountering this error:

amqp: link closed

while trying to send events to eventhub using the Send API:
https://pkg.go.dev/github.com/Azure/azure-event-hubs-go/[email protected]#Hub.Send

I don't have details on how long the connection was idle before this happened, but I would expect the library to handle this error and reconnect instead.

Environment

  • OS: Docker image running on k8s
  • Go version: 1.16
  • Version of Library: Eventhub - v3.3.16 and AMQP - v3.2.2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.