From 668d9fb05d1345bfcd8a894a5d5fad551bf0da36 Mon Sep 17 00:00:00 2001 From: d98762625 Date: Fri, 27 Mar 2020 08:53:38 +0000 Subject: [PATCH 1/3] Add dynamic node properties --- go/src/qpid.apache.org/electron/link.go | 7 +- go/src/qpid.apache.org/proton/wrappers.go | 82 +++++++++++++++++++++++ 2 files changed, 88 insertions(+), 1 deletion(-) diff --git a/go/src/qpid.apache.org/electron/link.go b/go/src/qpid.apache.org/electron/link.go index dd974f500a..a09955a7b0 100644 --- a/go/src/qpid.apache.org/electron/link.go +++ b/go/src/qpid.apache.org/electron/link.go @@ -21,9 +21,10 @@ package electron import ( "fmt" + "time" + "qpid.apache.org/amqp" "qpid.apache.org/proton" - "time" ) // Settings associated with a link @@ -183,6 +184,7 @@ type TerminusSettings struct { Expiry proton.ExpiryPolicy Timeout time.Duration Dynamic bool + Properties map[string]interface{} } func makeTerminusSettings(t proton.Terminus) TerminusSettings { @@ -191,6 +193,7 @@ func makeTerminusSettings(t proton.Terminus) TerminusSettings { Expiry: t.ExpiryPolicy(), Timeout: t.Timeout(), Dynamic: t.IsDynamic(), + Properties: t.GetProperties(), } } @@ -248,12 +251,14 @@ func makeLocalLink(sn *session, isSender bool, setting ...LinkOption) (linkSetti l.pLink.Source().SetExpiryPolicy(l.sourceSettings.Expiry) l.pLink.Source().SetTimeout(l.sourceSettings.Timeout) l.pLink.Source().SetDynamic(l.sourceSettings.Dynamic) + l.pLink.Source().SetProperties(l.sourceSettings.Properties) l.pLink.Target().SetAddress(l.target) l.pLink.Target().SetDurability(l.targetSettings.Durability) l.pLink.Target().SetExpiryPolicy(l.targetSettings.Expiry) l.pLink.Target().SetTimeout(l.targetSettings.Timeout) l.pLink.Target().SetDynamic(l.targetSettings.Dynamic) + l.pLink.Target().SetProperties(l.targetSettings.Properties) l.pLink.SetSndSettleMode(proton.SndSettleMode(l.sndSettle)) l.pLink.SetRcvSettleMode(proton.RcvSettleMode(l.rcvSettle)) diff --git a/go/src/qpid.apache.org/proton/wrappers.go b/go/src/qpid.apache.org/proton/wrappers.go index 42b2a23e7f..76a36b130f 100644 --- a/go/src/qpid.apache.org/proton/wrappers.go +++ b/go/src/qpid.apache.org/proton/wrappers.go @@ -453,3 +453,85 @@ func (t Transport) SASL() SASL { func SASLExtended() bool { return bool(C.pn_sasl_extended()) } + +// GetProperties returns the map of dynamic-node-properties for the terminus +// See section 3.5.9 in AMQP Specification v1.0 revision 1350 for more information +func (t Terminus) GetProperties() map[string]interface{} { + properties := map[string]interface{}{} + pn_data := C.pn_terminus_properties(t.pn) + size := int(C.pn_data_get_map(pn_data)) + if size <= 0 { + return nil + } + C.pn_data_enter(pn_data) + for i := 0; i < size/2; i++ { + key := "empty" + // read key (Must be a symbol keyed map) + if C.pn_data_next(pn_data) { + switch C.pn_data_type(pn_data) { + case C.PN_SYMBOL: + csymbol := C.pn_data_get_symbol(pn_data) + key = C.GoString(csymbol.start) + default: + + } + } + // read value + if C.pn_data_next(pn_data) { + switch C.pn_data_type(pn_data) { + case C.PN_INT: + value := int(C.pn_data_get_int(pn_data)) + properties[key] = value + case C.PN_SYMBOL: + csymbol := C.pn_data_get_symbol(pn_data) + value := C.GoString(csymbol.start) + properties[key] = value + case C.PN_STRING: + value := C.pn_data_get_string(pn_data) + properties[key] = value + } + } + } + C.pn_data_exit(pn_data) + return properties +} + +// SetProperties sets the map of dynamic-node-properties for the terminus +// See section 3.5.9 in AMQP Specification v1.0 revision 1350 for more information +func (t Terminus) SetProperties(properties map[string]interface{}) { + pn_data := C.pn_terminus_properties(t.pn) + if properties == nil || len(properties) <= 0 { + return + } + C.pn_data_clear(pn_data) + C.pn_data_put_map(pn_data) + C.pn_data_enter(pn_data) + for key, val := range properties { + // Put the key in the map + keyCStr := C.CString(key) + defer C.free(unsafe.Pointer(keyCStr)) + keyCStrLen := C.pn_decimal64_t(uint64(len(key))) + keyCStrBytes := C.pn_bytes(keyCStrLen, keyCStr) + C.pn_data_put_symbol(pn_data, keyCStrBytes) + + // Put the value in the map + switch val.(type) { + case int: + C.pn_data_put_int(pn_data, C.int(val.(int))) + case string: + valCStr := C.CString(val.(string)) + defer C.free(unsafe.Pointer(valCStr)) + valCStrLen := C.pn_decimal64_t(uint64(len(val.(string)))) + valCStrBytes := C.pn_bytes(valCStrLen, valCStr) + C.pn_data_put_symbol(pn_data, valCStrBytes) + default: + unknown := "unknown" + valCStr := C.CString(unknown) + defer C.free(unsafe.Pointer(valCStr)) + valCStrLen := C.pn_decimal64_t(uint64(len(unknown))) + valCStrBytes := C.pn_bytes(valCStrLen, valCStr) + C.pn_data_put_string(pn_data, valCStrBytes) + } + } + C.pn_data_exit(pn_data) +} From 54ca7193aead25686d052ead852a98124f15a477 Mon Sep 17 00:00:00 2001 From: d98762625 Date: Fri, 27 Mar 2020 12:32:29 +0000 Subject: [PATCH 2/3] use size_t for lengths in dynamic node properties --- go/pkg/proton/wrappers.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go/pkg/proton/wrappers.go b/go/pkg/proton/wrappers.go index 8b0c8b9101..e7d202ebbf 100644 --- a/go/pkg/proton/wrappers.go +++ b/go/pkg/proton/wrappers.go @@ -510,7 +510,7 @@ func (t Terminus) SetProperties(properties map[string]interface{}) { // Put the key in the map keyCStr := C.CString(key) defer C.free(unsafe.Pointer(keyCStr)) - keyCStrLen := C.pn_string_size(key) + keyCStrLen := C.size_t(len(key)) keyCStrBytes := C.pn_bytes(keyCStrLen, keyCStr) C.pn_data_put_symbol(pn_data, keyCStrBytes) @@ -521,14 +521,14 @@ func (t Terminus) SetProperties(properties map[string]interface{}) { case string: valCStr := C.CString(val.(string)) defer C.free(unsafe.Pointer(valCStr)) - valCStrLen := C.pn_string_size(val.(string)) + valCStrLen := C.size_t(len(val.(string))) valCStrBytes := C.pn_bytes(valCStrLen, valCStr) C.pn_data_put_symbol(pn_data, valCStrBytes) default: unknown := "unknown" valCStr := C.CString(unknown) defer C.free(unsafe.Pointer(valCStr)) - valCStrLen := C.pn_string_size(unknown) + valCStrLen := C.size_t(len(unknown)) valCStrBytes := C.pn_bytes(valCStrLen, valCStr) C.pn_data_put_string(pn_data, valCStrBytes) } From 065c4b6e64e581b170a424bb5727f39c305ef3d5 Mon Sep 17 00:00:00 2001 From: d98762625 Date: Fri, 27 Mar 2020 12:43:28 +0000 Subject: [PATCH 3/3] remove invalid test cases --- go/pkg/amqp/url_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/go/pkg/amqp/url_test.go b/go/pkg/amqp/url_test.go index 192e2fb04e..281057d4e4 100644 --- a/go/pkg/amqp/url_test.go +++ b/go/pkg/amqp/url_test.go @@ -32,13 +32,6 @@ func ExampleParseURL() { "amqps://host", "/path", "", - ":1234", - // Taken out because the go 1.4 URL parser isn't the same as later - //"[::1]", - //"[::1", - // Output would be: - // amqp://[::1]:amqp - // parse amqp://[::1: missing ']' in host } { u, err := ParseURL(s) if err != nil { @@ -55,5 +48,4 @@ func ExampleParseURL() { // amqps://host:amqps // amqp://localhost:amqp/path // amqp://localhost:amqp - // parse :1234: missing protocol scheme }