You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/02/23 22:51:45 UTC
[38/38] qpid-proton git commit: PROTON-1415: Merge branch 'master'
into go1
PROTON-1415: Merge branch 'master' into go1
Merge DurableSubscription changes.
Also merge restored compatibility back to proton-c 0.10
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/569b4fca
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/569b4fca
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/569b4fca
Branch: refs/heads/go1
Commit: 569b4fca1ecf733bee925cd1abf33541456cf630
Parents: ed8e879 9ec97b5
Author: Alan Conway <ac...@redhat.com>
Authored: Thu Feb 23 17:50:40 2017 -0500
Committer: Alan Conway <ac...@redhat.com>
Committed: Thu Feb 23 17:50:40 2017 -0500
----------------------------------------------------------------------
amqp/version.go | 8 ++-
electron/connection.go | 2 +-
electron/link.go | 128 +++++++++++++++++++++++++++++++++-----------
electron/link_test.go | 64 ++++++++++++++++++++++
proton/wrappers_gen.go | 8 +--
readme-go-get.md | 1 +
6 files changed, 174 insertions(+), 37 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/569b4fca/amqp/version.go
----------------------------------------------------------------------
diff --cc amqp/version.go
index cefa904,0000000..bf33d2b
mode 100644,000000..100644
--- a/amqp/version.go
+++ b/amqp/version.go
@@@ -1,29 -1,0 +1,35 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
++//
++// NOTE: DO NOT EDIT. This file was generated by genwrap.go from the proton header files.
++// Update the generator and re-run if you need to modify this code.
++//
++
++
+package amqp
+
+// Version check for proton library.
+// Done here because this is the lowest-level dependency for all the proton Go packages.
+
+// #include <proton/version.h>
- // #if PN_VERSION_MINOR < 10
++// #if PN_VERSION_MAJOR == 0 && PN_VERSION_MINOR < 10
+// #error packages qpid.apache.org/... require Proton-C library version 0.10 or greater
+// #endif
+import "C"
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/569b4fca/electron/connection.go
----------------------------------------------------------------------
diff --cc electron/connection.go
index 7f3050f,0000000..8f62491
mode 100644,000000..100644
--- a/electron/connection.go
+++ b/electron/connection.go
@@@ -1,405 -1,0 +1,405 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package electron
+
+// #include <proton/disposition.h>
+import "C"
+
+import (
+ "net"
+ "qpid.apache.org/proton"
+ "sync"
+ "time"
+)
+
+// Settings associated with a Connection.
+type ConnectionSettings interface {
+ // Authenticated user name associated with the connection.
+ User() string
+
+ // The AMQP virtual host name for the connection.
+ //
+ // Optional, useful when the server has multiple names and provides different
+ // service based on the name the client uses to connect.
+ //
+ // By default it is set to the DNS host name that the client uses to connect,
+ // but it can be set to something different at the client side with the
+ // VirtualHost() option.
+ //
+ // Returns error if the connection fails to authenticate.
+ VirtualHost() string
+
+ // Heartbeat is the maximum delay between sending frames that the remote peer
+ // has requested of us. If the interval expires an empty "heartbeat" frame
+ // will be sent automatically to keep the connection open.
+ Heartbeat() time.Duration
+}
+
+// Connection is an AMQP connection, created by a Container.
+type Connection interface {
+ Endpoint
+ ConnectionSettings
+
+ // Sender opens a new sender on the DefaultSession.
+ Sender(...LinkOption) (Sender, error)
+
+ // Receiver opens a new Receiver on the DefaultSession().
+ Receiver(...LinkOption) (Receiver, error)
+
+ // DefaultSession() returns a default session for the connection. It is opened
+ // on the first call to DefaultSession and returned on subsequent calls.
+ DefaultSession() (Session, error)
+
+ // Session opens a new session.
+ Session(...SessionOption) (Session, error)
+
+ // Container for the connection.
+ Container() Container
+
+ // Disconnect the connection abruptly with an error.
+ Disconnect(error)
+
+ // Wait waits for the connection to be disconnected.
+ Wait() error
+
+ // WaitTimeout is like Wait but returns Timeout if the timeout expires.
+ WaitTimeout(time.Duration) error
+
+ // Incoming returns a channel for incoming endpoints opened by the remote peer.
+ // See the Incoming interface for more.
+ //
+ // Not receiving from Incoming() and calling Accept/Reject will block the
+ // electron event loop. You should run a loop to handle the types that
+ // interest you in a switch{} and and Accept() all others.
+ Incoming() <-chan Incoming
+}
+
+type connectionSettings struct {
+ user, virtualHost string
+ heartbeat time.Duration
+}
+
+func (c connectionSettings) User() string { return c.user }
+func (c connectionSettings) VirtualHost() string { return c.virtualHost }
+func (c connectionSettings) Heartbeat() time.Duration { return c.heartbeat }
+
+// ConnectionOption can be passed when creating a connection to configure various options
+type ConnectionOption func(*connection)
+
+// User returns a ConnectionOption sets the user name for a connection
+func User(user string) ConnectionOption {
+ return func(c *connection) {
+ c.user = user
+ c.pConnection.SetUser(user)
+ }
+}
+
+// VirtualHost returns a ConnectionOption to set the AMQP virtual host for the connection.
+// Only applies to outbound client connection.
+func VirtualHost(virtualHost string) ConnectionOption {
+ return func(c *connection) {
+ c.virtualHost = virtualHost
+ c.pConnection.SetHostname(virtualHost)
+ }
+}
+
+// Password returns a ConnectionOption to set the password used to establish a
+// connection. Only applies to outbound client connection.
+//
+// The connection will erase its copy of the password from memory as soon as it
+// has been used to authenticate. If you are concerned about paswords staying in
+// memory you should never store them as strings, and should overwrite your
+// copy as soon as you are done with it.
+//
+func Password(password []byte) ConnectionOption {
+ return func(c *connection) { c.pConnection.SetPassword(password) }
+}
+
+// Server returns a ConnectionOption to put the connection in server mode for incoming connections.
+//
+// A server connection will do protocol negotiation to accept a incoming AMQP
+// connection. Normally you would call this for a connection created by
+// net.Listener.Accept()
+//
+func Server() ConnectionOption {
+ return func(c *connection) { c.engine.Server(); c.server = true; AllowIncoming()(c) }
+}
+
+// AllowIncoming returns a ConnectionOption to enable incoming endpoints, see
+// Connection.Incoming() This is automatically set for Server() connections.
+func AllowIncoming() ConnectionOption {
+ return func(c *connection) { c.incoming = make(chan Incoming) }
+}
+
+// Parent returns a ConnectionOption that associates the Connection with it's Container
+// If not set a connection will create its own default container.
+func Parent(cont Container) ConnectionOption {
+ return func(c *connection) { c.container = cont.(*container) }
+}
+
+type connection struct {
+ endpoint
+ connectionSettings
+
+ defaultSessionOnce, closeOnce sync.Once
+
+ container *container
+ conn net.Conn
+ server bool
+ incoming chan Incoming
+ handler *handler
+ engine *proton.Engine
+ pConnection proton.Connection
+
+ defaultSession Session
+}
+
+// NewConnection creates a connection with the given options.
+func NewConnection(conn net.Conn, opts ...ConnectionOption) (*connection, error) {
+ c := &connection{
+ conn: conn,
+ }
+ c.handler = newHandler(c)
+ var err error
+ c.engine, err = proton.NewEngine(c.conn, c.handler.delegator)
+ if err != nil {
+ return nil, err
+ }
+ c.pConnection = c.engine.Connection()
+ for _, set := range opts {
+ set(c)
+ }
+ if c.container == nil {
+ c.container = NewContainer("").(*container)
+ }
+ c.pConnection.SetContainer(c.container.Id())
+ globalSASLInit(c.engine)
+
+ c.endpoint.init(c.engine.String())
+ go c.run()
+ return c, nil
+}
+
+func (c *connection) run() {
+ if !c.server {
+ c.pConnection.Open()
+ }
+ _ = c.engine.Run()
+ if c.incoming != nil {
+ close(c.incoming)
+ }
+ _ = c.closed(Closed)
+}
+
+func (c *connection) Close(err error) {
+ c.err.Set(err)
+ c.engine.Close(err)
+}
+
+func (c *connection) Disconnect(err error) {
+ c.err.Set(err)
+ c.engine.Disconnect(err)
+}
+
+func (c *connection) Session(opts ...SessionOption) (Session, error) {
+ var s Session
+ err := c.engine.InjectWait(func() error {
+ if c.Error() != nil {
+ return c.Error()
+ }
+ pSession, err := c.engine.Connection().Session()
+ if err == nil {
+ pSession.Open()
+ if err == nil {
+ s = newSession(c, pSession, opts...)
+ }
+ }
+ return err
+ })
+ return s, err
+}
+
+func (c *connection) Container() Container { return c.container }
+
+func (c *connection) DefaultSession() (s Session, err error) {
+ c.defaultSessionOnce.Do(func() {
+ c.defaultSession, err = c.Session()
+ })
+ if err == nil {
+ err = c.Error()
+ }
+ return c.defaultSession, err
+}
+
+func (c *connection) Sender(opts ...LinkOption) (Sender, error) {
+ if s, err := c.DefaultSession(); err == nil {
+ return s.Sender(opts...)
+ } else {
+ return nil, err
+ }
+}
+
+func (c *connection) Receiver(opts ...LinkOption) (Receiver, error) {
+ if s, err := c.DefaultSession(); err == nil {
+ return s.Receiver(opts...)
+ } else {
+ return nil, err
+ }
+}
+
+func (c *connection) Connection() Connection { return c }
+
+func (c *connection) Wait() error { return c.WaitTimeout(Forever) }
+func (c *connection) WaitTimeout(timeout time.Duration) error {
+ _, err := timedReceive(c.done, timeout)
+ if err == Timeout {
+ return Timeout
+ }
+ return c.Error()
+}
+
+func (c *connection) Incoming() <-chan Incoming {
- assert(c.incoming != nil, "electron.Connection.Incoming() disabled for %s", c)
++ assert(c.incoming != nil, "Incoming() is only allowed for a Connection created with the Server() option: %s", c)
+ return c.incoming
+}
+
+type IncomingConnection struct {
+ incoming
+ connectionSettings
+ c *connection
+}
+
+func newIncomingConnection(c *connection) *IncomingConnection {
+ c.user = c.pConnection.Transport().User()
+ c.virtualHost = c.pConnection.RemoteHostname()
+ return &IncomingConnection{
+ incoming: makeIncoming(c.pConnection),
+ connectionSettings: c.connectionSettings,
+ c: c}
+}
+
+// AcceptConnection is like Accept() but takes ConnectionOption s
+// For example you can set the Heartbeat() for the accepted connection.
+func (in *IncomingConnection) AcceptConnection(opts ...ConnectionOption) Connection {
+ return in.accept(func() Endpoint {
+ for _, opt := range opts {
+ opt(in.c)
+ }
+ in.c.pConnection.Open()
+ return in.c
+ }).(Connection)
+}
+
+func (in *IncomingConnection) Accept() Endpoint {
+ return in.AcceptConnection()
+}
+
+func sasl(c *connection) proton.SASL { return c.engine.Transport().SASL() }
+
+// SASLEnable returns a ConnectionOption that enables SASL authentication.
+// Only required if you don't set any other SASL options.
+func SASLEnable() ConnectionOption { return func(c *connection) { sasl(c) } }
+
+// SASLAllowedMechs returns a ConnectionOption to set the list of allowed SASL
+// mechanisms.
+//
+// Can be used on the client or the server to restrict the SASL for a connection.
+// mechs is a space-separated list of mechanism names.
+//
+func SASLAllowedMechs(mechs string) ConnectionOption {
+ return func(c *connection) { sasl(c).AllowedMechs(mechs) }
+}
+
+// SASLAllowInsecure returns a ConnectionOption that allows or disallows clear
+// text SASL authentication mechanisms
+//
+// By default the SASL layer is configured not to allow mechanisms that disclose
+// the clear text of the password over an unencrypted AMQP connection. This specifically
+// will disallow the use of the PLAIN mechanism without using SSL encryption.
+//
+// This default is to avoid disclosing password information accidentally over an
+// insecure network.
+//
+func SASLAllowInsecure(b bool) ConnectionOption {
+ return func(c *connection) { sasl(c).SetAllowInsecureMechs(b) }
+}
+
+// Heartbeat returns a ConnectionOption that requests the maximum delay
+// between sending frames for the remote peer. If we don't receive any frames
+// within 2*delay we will close the connection.
+//
+func Heartbeat(delay time.Duration) ConnectionOption {
+ // Proton-C divides the idle-timeout by 2 before sending, so compensate.
+ return func(c *connection) { c.engine.Transport().SetIdleTimeout(2 * delay) }
+}
+
+// GlobalSASLConfigDir sets the SASL configuration directory for every
+// Connection created in this process. If not called, the default is determined
+// by your SASL installation.
+//
+// You can set SASLAllowInsecure and SASLAllowedMechs on individual connections.
+//
+func GlobalSASLConfigDir(dir string) { globalSASLConfigDir = dir }
+
+// GlobalSASLConfigName sets the SASL configuration name for every Connection
+// created in this process. If not called the default is "proton-server".
+//
+// The complete configuration file name is
+// <sasl-config-dir>/<sasl-config-name>.conf
+//
+// You can set SASLAllowInsecure and SASLAllowedMechs on individual connections.
+//
+func GlobalSASLConfigName(dir string) { globalSASLConfigName = dir }
+
+var (
+ globalSASLConfigName string
+ globalSASLConfigDir string
+)
+
+// TODO aconway 2016-09-15: Current pn_sasl C impl config is broken, so all we
+// can realistically offer is global configuration. Later if/when the pn_sasl C
+// impl is fixed we can offer per connection over-rides.
+func globalSASLInit(eng *proton.Engine) {
+ sasl := eng.Transport().SASL()
+ if globalSASLConfigName != "" {
+ sasl.ConfigName(globalSASLConfigName)
+ }
+ if globalSASLConfigDir != "" {
+ sasl.ConfigPath(globalSASLConfigDir)
+ }
+}
+
+// Dial is shorthand for using net.Dial() then NewConnection()
+func Dial(network, addr string, opts ...ConnectionOption) (c Connection, err error) {
+ conn, err := net.Dial(network, addr)
+ if err == nil {
+ c, err = NewConnection(conn, opts...)
+ }
+ return
+}
+
+// DialWithDialer is shorthand for using dialer.Dial() then NewConnection()
+func DialWithDialer(dialer *net.Dialer, network, addr string, opts ...ConnectionOption) (c Connection, err error) {
+ conn, err := dialer.Dial(network, addr)
+ if err == nil {
+ c, err = NewConnection(conn, opts...)
+ }
+ return
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/569b4fca/electron/link.go
----------------------------------------------------------------------
diff --cc electron/link.go
index 1d17894,0000000..4f927c1
mode 100644,000000..100644
--- a/electron/link.go
+++ b/electron/link.go
@@@ -1,221 -1,0 +1,285 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+package electron
+
+import (
+ "fmt"
+ "qpid.apache.org/proton"
++ "time"
+)
+
+// Settings associated with a link
+type LinkSettings interface {
+ // Source address that messages are coming from.
+ Source() string
+
+ // Target address that messages are going to.
+ Target() string
+
+ // Name is a unique name for the link among links between the same
+ // containers in the same direction. By default generated automatically.
+ LinkName() string
+
+ // IsSender is true if this is the sending end of the link.
+ IsSender() bool
+
+ // IsReceiver is true if this is the receiving end of the link.
+ IsReceiver() bool
+
+ // SndSettle defines when the sending end of the link settles message delivery.
+ SndSettle() SndSettleMode
+
+ // RcvSettle defines when the sending end of the link settles message delivery.
+ RcvSettle() RcvSettleMode
+
+ // Session containing the Link
+ Session() Session
++
++ // Advanced settings for the source
++ SourceSettings() TerminusSettings
++
++ // Advanced settings for the target
++ TargetSettings() TerminusSettings
+}
+
+// LinkOption can be passed when creating a sender or receiver link to set optional configuration.
+type LinkOption func(*linkSettings)
+
+// Source returns a LinkOption that sets address that messages are coming from.
+func Source(s string) LinkOption { return func(l *linkSettings) { l.source = s } }
+
+// Target returns a LinkOption that sets address that messages are going to.
+func Target(s string) LinkOption { return func(l *linkSettings) { l.target = s } }
+
+// LinkName returns a LinkOption that sets the link name.
- func LinkName(s string) LinkOption { return func(l *linkSettings) { l.target = s } }
++func LinkName(s string) LinkOption { return func(l *linkSettings) { l.linkName = s } }
+
+// SndSettle returns a LinkOption that sets the send settle mode
+func SndSettle(m SndSettleMode) LinkOption { return func(l *linkSettings) { l.sndSettle = m } }
+
+// RcvSettle returns a LinkOption that sets the send settle mode
+func RcvSettle(m RcvSettleMode) LinkOption { return func(l *linkSettings) { l.rcvSettle = m } }
+
- // SndSettleMode returns a LinkOption that defines when the sending end of the
- // link settles message delivery.
- type SndSettleMode proton.SndSettleMode
-
+// Capacity returns a LinkOption that sets the link capacity
+func Capacity(n int) LinkOption { return func(l *linkSettings) { l.capacity = n } }
+
+// Prefetch returns a LinkOption that sets a receivers pre-fetch flag. Not relevant for a sender.
+func Prefetch(p bool) LinkOption { return func(l *linkSettings) { l.prefetch = p } }
+
++// DurableSubscription returns a LinkOption that configures a Receiver as a named durable
++// subscription. The name overrides (and is overridden by) LinkName() so you should normally
++// only use one of these options.
++func DurableSubscription(name string) LinkOption {
++ return func(l *linkSettings) {
++ l.linkName = name
++ l.sourceSettings.Durability = proton.Deliveries
++ l.sourceSettings.Expiry = proton.ExpireNever
++ }
++}
++
+// AtMostOnce returns a LinkOption that sets "fire and forget" mode, messages
+// are sent but no acknowledgment is received, messages can be lost if there is
+// a network failure. Sets SndSettleMode=SendSettled and RcvSettleMode=RcvFirst
+func AtMostOnce() LinkOption {
+ return func(l *linkSettings) {
+ SndSettle(SndSettled)(l)
+ RcvSettle(RcvFirst)(l)
+ }
+}
+
+// AtLeastOnce returns a LinkOption that requests acknowledgment for every
+// message, acknowledgment indicates the message was definitely received. In the
+// event of a failure, unacknowledged messages can be re-sent but there is a
+// chance that the message will be received twice in this case. Sets
+// SndSettleMode=SndUnsettled and RcvSettleMode=RcvFirst
+func AtLeastOnce() LinkOption {
+ return func(l *linkSettings) {
+ SndSettle(SndUnsettled)(l)
+ RcvSettle(RcvFirst)(l)
+ }
+}
+
++// SourceSettings returns a LinkOption that sets all the SourceSettings.
++// Note: it will override the source address set by a Source() option
++func SourceSettings(ts TerminusSettings) LinkOption {
++ return func(l *linkSettings) { l.sourceSettings = ts }
++}
++
++// TargetSettings returns a LinkOption that sets all the TargetSettings.
++// Note: it will override the target address set by a Target() option
++func TargetSettings(ts TerminusSettings) LinkOption {
++ return func(l *linkSettings) { l.targetSettings = ts }
++}
++
++// SndSettleMode defines when the sending end of the link settles message delivery.
++type SndSettleMode proton.SndSettleMode
++
+const (
+ // Messages are sent unsettled
+ SndUnsettled = SndSettleMode(proton.SndUnsettled)
+ // Messages are sent already settled
+ SndSettled = SndSettleMode(proton.SndSettled)
+ // Sender can send either unsettled or settled messages.
+ SendMixed = SndSettleMode(proton.SndMixed)
+)
+
+// RcvSettleMode defines when the receiving end of the link settles message delivery.
+type RcvSettleMode proton.RcvSettleMode
+
+const (
+ // Receiver settles first.
+ RcvFirst = RcvSettleMode(proton.RcvFirst)
+ // Receiver waits for sender to settle before settling.
+ RcvSecond = RcvSettleMode(proton.RcvSecond)
+)
+
+type linkSettings struct {
- source string
- target string
- linkName string
- isSender bool
- sndSettle SndSettleMode
- rcvSettle RcvSettleMode
- capacity int
- prefetch bool
- session *session
- pLink proton.Link
++ source string
++ sourceSettings TerminusSettings
++ target string
++ targetSettings TerminusSettings
++ linkName string
++ isSender bool
++ sndSettle SndSettleMode
++ rcvSettle RcvSettleMode
++ capacity int
++ prefetch bool
++ session *session
++ pLink proton.Link
++}
++
++// Advanced AMQP settings for the source or target of a link.
++// Usually these can be set via a more descriptive LinkOption, e.g. DurableSubscription()
++// and do not need to be set/examined directly.
++type TerminusSettings struct {
++ Durability proton.Durability
++ Expiry proton.ExpiryPolicy
++ Timeout time.Duration
++ Dynamic bool
++}
++
++func makeTerminusSettings(t proton.Terminus) TerminusSettings {
++ return TerminusSettings{
++ Durability: t.Durability(),
++ Expiry: t.ExpiryPolicy(),
++ Timeout: t.Timeout(),
++ Dynamic: t.IsDynamic(),
++ }
+}
+
+type link struct {
+ endpoint
+ linkSettings
+}
+
- func (l *linkSettings) Source() string { return l.source }
- func (l *linkSettings) Target() string { return l.target }
- func (l *linkSettings) LinkName() string { return l.linkName }
- func (l *linkSettings) IsSender() bool { return l.isSender }
- func (l *linkSettings) IsReceiver() bool { return !l.isSender }
- func (l *linkSettings) SndSettle() SndSettleMode { return l.sndSettle }
- func (l *linkSettings) RcvSettle() RcvSettleMode { return l.rcvSettle }
++func (l *linkSettings) Source() string { return l.source }
++func (l *linkSettings) Target() string { return l.target }
++func (l *linkSettings) LinkName() string { return l.linkName }
++func (l *linkSettings) IsSender() bool { return l.isSender }
++func (l *linkSettings) IsReceiver() bool { return !l.isSender }
++func (l *linkSettings) SndSettle() SndSettleMode { return l.sndSettle }
++func (l *linkSettings) RcvSettle() RcvSettleMode { return l.rcvSettle }
++func (l *linkSettings) SourceSettings() TerminusSettings { return l.sourceSettings }
++func (l *linkSettings) TargetSettings() TerminusSettings { return l.targetSettings }
+
+func (l *link) Session() Session { return l.session }
+func (l *link) Connection() Connection { return l.session.Connection() }
+func (l *link) engine() *proton.Engine { return l.session.connection.engine }
+func (l *link) handler() *handler { return l.session.connection.handler }
+
+// Open a link and return the linkSettings.
+func makeLocalLink(sn *session, isSender bool, setting ...LinkOption) (linkSettings, error) {
+ l := linkSettings{
+ isSender: isSender,
+ capacity: 1,
+ prefetch: false,
+ session: sn,
+ }
+ for _, set := range setting {
+ set(&l)
+ }
+ if l.linkName == "" {
+ l.linkName = l.session.connection.container.nextLinkName()
+ }
+ if l.IsSender() {
+ l.pLink = l.session.pSession.Sender(l.linkName)
+ } else {
+ l.pLink = l.session.pSession.Receiver(l.linkName)
+ }
+ if l.pLink.IsNil() {
+ return l, fmt.Errorf("cannot create link %s", l.pLink)
+ }
+ l.pLink.Source().SetAddress(l.source)
++ l.pLink.Source().SetDurability(l.sourceSettings.Durability)
++ l.pLink.Source().SetExpiryPolicy(l.sourceSettings.Expiry)
++ l.pLink.Source().SetTimeout(l.sourceSettings.Timeout)
++ l.pLink.Source().SetDynamic(l.sourceSettings.Dynamic)
++
+ 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.SetSndSettleMode(proton.SndSettleMode(l.sndSettle))
+ l.pLink.SetRcvSettleMode(proton.RcvSettleMode(l.rcvSettle))
+ l.pLink.Open()
+ return l, nil
+}
+
+func makeIncomingLinkSettings(pLink proton.Link, sn *session) linkSettings {
+ return linkSettings{
- isSender: pLink.IsSender(),
- source: pLink.RemoteSource().Address(),
- target: pLink.RemoteTarget().Address(),
- linkName: pLink.Name(),
- sndSettle: SndSettleMode(pLink.RemoteSndSettleMode()),
- rcvSettle: RcvSettleMode(pLink.RemoteRcvSettleMode()),
- capacity: 1,
- prefetch: false,
- pLink: pLink,
- session: sn,
++ isSender: pLink.IsSender(),
++ source: pLink.RemoteSource().Address(),
++ sourceSettings: makeTerminusSettings(pLink.RemoteSource()),
++ target: pLink.RemoteTarget().Address(),
++ targetSettings: makeTerminusSettings(pLink.RemoteTarget()),
++ linkName: pLink.Name(),
++ sndSettle: SndSettleMode(pLink.RemoteSndSettleMode()),
++ rcvSettle: RcvSettleMode(pLink.RemoteRcvSettleMode()),
++ capacity: 1,
++ prefetch: false,
++ pLink: pLink,
++ session: sn,
+ }
+}
+
+// Not part of Link interface but use by Sender and Receiver.
+func (l *link) Credit() (credit int, err error) {
+ err = l.engine().InjectWait(func() error {
+ if l.Error() != nil {
+ return l.Error()
+ }
+ credit = l.pLink.Credit()
+ return nil
+ })
+ return
+}
+
+// Not part of Link interface but use by Sender and Receiver.
+func (l *link) Capacity() int { return l.capacity }
+
+func (l *link) Close(err error) {
+ _ = l.engine().Inject(func() {
+ if l.Error() == nil {
+ localClose(l.pLink, err)
+ }
+ })
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/569b4fca/electron/link_test.go
----------------------------------------------------------------------
diff --cc electron/link_test.go
index 0000000,0000000..133faad
new file mode 100644
--- /dev/null
+++ b/electron/link_test.go
@@@ -1,0 -1,0 +1,64 @@@
++/*
++Licensed to the Apache Software Foundation (ASF) under one
++or more contributor license agreements. See the NOTICE file
++distributed with this work for additional information
++regarding copyright ownership. The ASF licenses this file
++to you under the Apache License, Version 2.0 (the
++"License"); you may not use this file except in compliance
++with the License. You may obtain a copy of the License at
++
++ http://www.apache.org/licenses/LICENSE-2.0
++
++Unless required by applicable law or agreed to in writing,
++software distributed under the License is distributed on an
++"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
++KIND, either express or implied. See the License for the
++specific language governing permissions and limitations
++under the License.
++*/
++
++// Test that link settings are propagated correctly
++package electron
++
++import (
++ "net"
++ "qpid.apache.org/proton"
++ "testing"
++ "time"
++)
++
++func TestLinkSettings(t *testing.T) {
++ cConn, sConn := net.Pipe()
++ done := make(chan error)
++ // FIXME aconway 2017-02-23: bug in timeout conversion (pn_second_t)
++ settings := TerminusSettings{Durability: 1, Expiry: 2, Timeout: 42 * time.Second, Dynamic: true}
++ go func() { // Server
++ close(done)
++ defer sConn.Close()
++ c, err := NewConnection(sConn, Server())
++ fatalIf(t, err)
++ for in := range c.Incoming() {
++ ep := in.Accept()
++ switch ep := ep.(type) {
++ case Receiver:
++ errorIf(t, checkEqual("one.source", ep.Source()))
++ errorIf(t, checkEqual(TerminusSettings{}, ep.SourceSettings()))
++ errorIf(t, checkEqual("one.target", ep.Target()))
++ errorIf(t, checkEqual(settings, ep.TargetSettings()))
++ case Sender:
++ errorIf(t, checkEqual("two", ep.LinkName()))
++ errorIf(t, checkEqual("two.source", ep.Source()))
++ errorIf(t, checkEqual(TerminusSettings{Durability: proton.Deliveries, Expiry: proton.ExpireNever}, ep.SourceSettings()))
++ }
++ }
++ }()
++
++ // Client
++ c, err := NewConnection(cConn)
++ fatalIf(t, err)
++ c.Sender(Source("one.source"), Target("one.target"), TargetSettings(settings))
++
++ c.Receiver(Source("two.source"), DurableSubscription("two"))
++ c.Close(nil)
++ <-done
++}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/569b4fca/proton/wrappers_gen.go
----------------------------------------------------------------------
diff --cc proton/wrappers_gen.go
index 19bfde2,0000000..0db04c8
mode 100644,000000..100644
--- a/proton/wrappers_gen.go
+++ b/proton/wrappers_gen.go
@@@ -1,937 -1,0 +1,939 @@@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+
+//
+// NOTE: DO NOT EDIT. This file was generated by genwrap.go from the proton header files.
+// Update the generator and re-run if you need to modify this code.
+//
+
+package proton
+
+import (
+ "time"
+ "unsafe"
+)
+
- // #include <proton/types.h>
- // #include <proton/error.h>
+// #include <proton/condition.h>
++// #include <proton/error.h>
+// #include <proton/event.h>
++// #include <proton/types.h>
+// #include <stdlib.h>
++import "C"
++
+// #include <proton/session.h>
+// #include <proton/link.h>
+// #include <proton/delivery.h>
+// #include <proton/disposition.h>
+// #include <proton/condition.h>
+// #include <proton/terminus.h>
+// #include <proton/connection.h>
+// #include <proton/transport.h>
+// #include <proton/sasl.h>
+import "C"
+
+type EventType int
+
+const (
+ EConnectionInit EventType = C.PN_CONNECTION_INIT
+ EConnectionBound EventType = C.PN_CONNECTION_BOUND
+ EConnectionUnbound EventType = C.PN_CONNECTION_UNBOUND
+ EConnectionLocalOpen EventType = C.PN_CONNECTION_LOCAL_OPEN
+ EConnectionRemoteOpen EventType = C.PN_CONNECTION_REMOTE_OPEN
+ EConnectionLocalClose EventType = C.PN_CONNECTION_LOCAL_CLOSE
+ EConnectionRemoteClose EventType = C.PN_CONNECTION_REMOTE_CLOSE
+ EConnectionFinal EventType = C.PN_CONNECTION_FINAL
+ ESessionInit EventType = C.PN_SESSION_INIT
+ ESessionLocalOpen EventType = C.PN_SESSION_LOCAL_OPEN
+ ESessionRemoteOpen EventType = C.PN_SESSION_REMOTE_OPEN
+ ESessionLocalClose EventType = C.PN_SESSION_LOCAL_CLOSE
+ ESessionRemoteClose EventType = C.PN_SESSION_REMOTE_CLOSE
+ ESessionFinal EventType = C.PN_SESSION_FINAL
+ ELinkInit EventType = C.PN_LINK_INIT
+ ELinkLocalOpen EventType = C.PN_LINK_LOCAL_OPEN
+ ELinkRemoteOpen EventType = C.PN_LINK_REMOTE_OPEN
+ ELinkLocalClose EventType = C.PN_LINK_LOCAL_CLOSE
+ ELinkRemoteClose EventType = C.PN_LINK_REMOTE_CLOSE
+ ELinkLocalDetach EventType = C.PN_LINK_LOCAL_DETACH
+ ELinkRemoteDetach EventType = C.PN_LINK_REMOTE_DETACH
+ ELinkFlow EventType = C.PN_LINK_FLOW
+ ELinkFinal EventType = C.PN_LINK_FINAL
+ EDelivery EventType = C.PN_DELIVERY
+ ETransport EventType = C.PN_TRANSPORT
+ ETransportAuthenticated EventType = C.PN_TRANSPORT_AUTHENTICATED
+ ETransportError EventType = C.PN_TRANSPORT_ERROR
+ ETransportHeadClosed EventType = C.PN_TRANSPORT_HEAD_CLOSED
+ ETransportTailClosed EventType = C.PN_TRANSPORT_TAIL_CLOSED
+ ETransportClosed EventType = C.PN_TRANSPORT_CLOSED
+)
+
+func (e EventType) String() string {
+ switch e {
+
+ case C.PN_CONNECTION_INIT:
+ return "ConnectionInit"
+ case C.PN_CONNECTION_BOUND:
+ return "ConnectionBound"
+ case C.PN_CONNECTION_UNBOUND:
+ return "ConnectionUnbound"
+ case C.PN_CONNECTION_LOCAL_OPEN:
+ return "ConnectionLocalOpen"
+ case C.PN_CONNECTION_REMOTE_OPEN:
+ return "ConnectionRemoteOpen"
+ case C.PN_CONNECTION_LOCAL_CLOSE:
+ return "ConnectionLocalClose"
+ case C.PN_CONNECTION_REMOTE_CLOSE:
+ return "ConnectionRemoteClose"
+ case C.PN_CONNECTION_FINAL:
+ return "ConnectionFinal"
+ case C.PN_SESSION_INIT:
+ return "SessionInit"
+ case C.PN_SESSION_LOCAL_OPEN:
+ return "SessionLocalOpen"
+ case C.PN_SESSION_REMOTE_OPEN:
+ return "SessionRemoteOpen"
+ case C.PN_SESSION_LOCAL_CLOSE:
+ return "SessionLocalClose"
+ case C.PN_SESSION_REMOTE_CLOSE:
+ return "SessionRemoteClose"
+ case C.PN_SESSION_FINAL:
+ return "SessionFinal"
+ case C.PN_LINK_INIT:
+ return "LinkInit"
+ case C.PN_LINK_LOCAL_OPEN:
+ return "LinkLocalOpen"
+ case C.PN_LINK_REMOTE_OPEN:
+ return "LinkRemoteOpen"
+ case C.PN_LINK_LOCAL_CLOSE:
+ return "LinkLocalClose"
+ case C.PN_LINK_REMOTE_CLOSE:
+ return "LinkRemoteClose"
+ case C.PN_LINK_LOCAL_DETACH:
+ return "LinkLocalDetach"
+ case C.PN_LINK_REMOTE_DETACH:
+ return "LinkRemoteDetach"
+ case C.PN_LINK_FLOW:
+ return "LinkFlow"
+ case C.PN_LINK_FINAL:
+ return "LinkFinal"
+ case C.PN_DELIVERY:
+ return "Delivery"
+ case C.PN_TRANSPORT:
+ return "Transport"
+ case C.PN_TRANSPORT_AUTHENTICATED:
+ return "TransportAuthenticated"
+ case C.PN_TRANSPORT_ERROR:
+ return "TransportError"
+ case C.PN_TRANSPORT_HEAD_CLOSED:
+ return "TransportHeadClosed"
+ case C.PN_TRANSPORT_TAIL_CLOSED:
+ return "TransportTailClosed"
+ case C.PN_TRANSPORT_CLOSED:
+ return "TransportClosed"
+ }
+ return "Unknown"
+}
+
+// Wrappers for declarations in session.h
+
+type Session struct{ pn *C.pn_session_t }
+
+func (s Session) IsNil() bool { return s.pn == nil }
+func (s Session) CPtr() unsafe.Pointer { return unsafe.Pointer(s.pn) }
+func (s Session) Free() {
+ C.pn_session_free(s.pn)
+}
+func (s Session) State() State {
+ return State(C.pn_session_state(s.pn))
+}
+func (s Session) Error() error {
+ return PnError(C.pn_session_error(s.pn))
+}
+func (s Session) Condition() Condition {
+ return Condition{C.pn_session_condition(s.pn)}
+}
+func (s Session) RemoteCondition() Condition {
+ return Condition{C.pn_session_remote_condition(s.pn)}
+}
+func (s Session) Connection() Connection {
+ return Connection{C.pn_session_connection(s.pn)}
+}
+func (s Session) Open() {
+ C.pn_session_open(s.pn)
+}
+func (s Session) Close() {
+ C.pn_session_close(s.pn)
+}
+func (s Session) IncomingCapacity() uint {
+ return uint(C.pn_session_get_incoming_capacity(s.pn))
+}
+func (s Session) SetIncomingCapacity(capacity uint) {
+ C.pn_session_set_incoming_capacity(s.pn, C.size_t(capacity))
+}
+func (s Session) OutgoingWindow() uint {
+ return uint(C.pn_session_get_outgoing_window(s.pn))
+}
+func (s Session) SetOutgoingWindow(window uint) {
+ C.pn_session_set_outgoing_window(s.pn, C.size_t(window))
+}
+func (s Session) OutgoingBytes() uint {
+ return uint(C.pn_session_outgoing_bytes(s.pn))
+}
+func (s Session) IncomingBytes() uint {
+ return uint(C.pn_session_incoming_bytes(s.pn))
+}
+func (s Session) Next(state State) Session {
+ return Session{C.pn_session_next(s.pn, C.pn_state_t(state))}
+}
+
+// Wrappers for declarations in link.h
+
+type SndSettleMode C.pn_snd_settle_mode_t
+
+const (
+ SndUnsettled SndSettleMode = C.PN_SND_UNSETTLED
+ SndSettled SndSettleMode = C.PN_SND_SETTLED
+ SndMixed SndSettleMode = C.PN_SND_MIXED
+)
+
+func (e SndSettleMode) String() string {
+ switch e {
+
+ case C.PN_SND_UNSETTLED:
+ return "SndUnsettled"
+ case C.PN_SND_SETTLED:
+ return "SndSettled"
+ case C.PN_SND_MIXED:
+ return "SndMixed"
+ }
+ return "unknown"
+}
+
+type RcvSettleMode C.pn_rcv_settle_mode_t
+
+const (
+ RcvFirst RcvSettleMode = C.PN_RCV_FIRST
+ RcvSecond RcvSettleMode = C.PN_RCV_SECOND
+)
+
+func (e RcvSettleMode) String() string {
+ switch e {
+
+ case C.PN_RCV_FIRST:
+ return "RcvFirst"
+ case C.PN_RCV_SECOND:
+ return "RcvSecond"
+ }
+ return "unknown"
+}
+
+type Link struct{ pn *C.pn_link_t }
+
+func (l Link) IsNil() bool { return l.pn == nil }
+func (l Link) CPtr() unsafe.Pointer { return unsafe.Pointer(l.pn) }
+func (l Link) Free() {
+ C.pn_link_free(l.pn)
+}
+func (l Link) Name() string {
+ return C.GoString(C.pn_link_name(l.pn))
+}
+func (l Link) IsSender() bool {
+ return bool(C.pn_link_is_sender(l.pn))
+}
+func (l Link) IsReceiver() bool {
+ return bool(C.pn_link_is_receiver(l.pn))
+}
+func (l Link) State() State {
+ return State(C.pn_link_state(l.pn))
+}
+func (l Link) Error() error {
+ return PnError(C.pn_link_error(l.pn))
+}
+func (l Link) Condition() Condition {
+ return Condition{C.pn_link_condition(l.pn)}
+}
+func (l Link) RemoteCondition() Condition {
+ return Condition{C.pn_link_remote_condition(l.pn)}
+}
+func (l Link) Session() Session {
+ return Session{C.pn_link_session(l.pn)}
+}
+func (l Link) Next(state State) Link {
+ return Link{C.pn_link_next(l.pn, C.pn_state_t(state))}
+}
+func (l Link) Open() {
+ C.pn_link_open(l.pn)
+}
+func (l Link) Close() {
+ C.pn_link_close(l.pn)
+}
+func (l Link) Detach() {
+ C.pn_link_detach(l.pn)
+}
+func (l Link) Source() Terminus {
+ return Terminus{C.pn_link_source(l.pn)}
+}
+func (l Link) Target() Terminus {
+ return Terminus{C.pn_link_target(l.pn)}
+}
+func (l Link) RemoteSource() Terminus {
+ return Terminus{C.pn_link_remote_source(l.pn)}
+}
+func (l Link) RemoteTarget() Terminus {
+ return Terminus{C.pn_link_remote_target(l.pn)}
+}
+func (l Link) Current() Delivery {
+ return Delivery{C.pn_link_current(l.pn)}
+}
+func (l Link) Advance() bool {
+ return bool(C.pn_link_advance(l.pn))
+}
+func (l Link) Credit() int {
+ return int(C.pn_link_credit(l.pn))
+}
+func (l Link) Queued() int {
+ return int(C.pn_link_queued(l.pn))
+}
+func (l Link) RemoteCredit() int {
+ return int(C.pn_link_remote_credit(l.pn))
+}
+func (l Link) Drained() int {
+ return int(C.pn_link_drained(l.pn))
+}
+func (l Link) Available() int {
+ return int(C.pn_link_available(l.pn))
+}
+func (l Link) SndSettleMode() SndSettleMode {
+ return SndSettleMode(C.pn_link_snd_settle_mode(l.pn))
+}
+func (l Link) RcvSettleMode() RcvSettleMode {
+ return RcvSettleMode(C.pn_link_rcv_settle_mode(l.pn))
+}
+func (l Link) SetSndSettleMode(mode SndSettleMode) {
+ C.pn_link_set_snd_settle_mode(l.pn, C.pn_snd_settle_mode_t(mode))
+}
+func (l Link) SetRcvSettleMode(mode RcvSettleMode) {
+ C.pn_link_set_rcv_settle_mode(l.pn, C.pn_rcv_settle_mode_t(mode))
+}
+func (l Link) RemoteSndSettleMode() SndSettleMode {
+ return SndSettleMode(C.pn_link_remote_snd_settle_mode(l.pn))
+}
+func (l Link) RemoteRcvSettleMode() RcvSettleMode {
+ return RcvSettleMode(C.pn_link_remote_rcv_settle_mode(l.pn))
+}
+func (l Link) Unsettled() int {
+ return int(C.pn_link_unsettled(l.pn))
+}
+func (l Link) Offered(credit int) {
+ C.pn_link_offered(l.pn, C.int(credit))
+}
+func (l Link) Flow(credit int) {
+ C.pn_link_flow(l.pn, C.int(credit))
+}
+func (l Link) Drain(credit int) {
+ C.pn_link_drain(l.pn, C.int(credit))
+}
+func (l Link) SetDrain(drain bool) {
+ C.pn_link_set_drain(l.pn, C.bool(drain))
+}
+func (l Link) Draining() bool {
+ return bool(C.pn_link_draining(l.pn))
+}
+
+// Wrappers for declarations in delivery.h
+
+type Delivery struct{ pn *C.pn_delivery_t }
+
+func (d Delivery) IsNil() bool { return d.pn == nil }
+func (d Delivery) CPtr() unsafe.Pointer { return unsafe.Pointer(d.pn) }
+func (d Delivery) Tag() DeliveryTag {
+ return DeliveryTag{C.pn_delivery_tag(d.pn)}
+}
+func (d Delivery) Link() Link {
+ return Link{C.pn_delivery_link(d.pn)}
+}
+func (d Delivery) Local() Disposition {
+ return Disposition{C.pn_delivery_local(d.pn)}
+}
+func (d Delivery) LocalState() uint64 {
+ return uint64(C.pn_delivery_local_state(d.pn))
+}
+func (d Delivery) Remote() Disposition {
+ return Disposition{C.pn_delivery_remote(d.pn)}
+}
+func (d Delivery) RemoteState() uint64 {
+ return uint64(C.pn_delivery_remote_state(d.pn))
+}
+func (d Delivery) Settled() bool {
+ return bool(C.pn_delivery_settled(d.pn))
+}
+func (d Delivery) Pending() uint {
+ return uint(C.pn_delivery_pending(d.pn))
+}
+func (d Delivery) Partial() bool {
+ return bool(C.pn_delivery_partial(d.pn))
+}
+func (d Delivery) Writable() bool {
+ return bool(C.pn_delivery_writable(d.pn))
+}
+func (d Delivery) Readable() bool {
+ return bool(C.pn_delivery_readable(d.pn))
+}
+func (d Delivery) Updated() bool {
+ return bool(C.pn_delivery_updated(d.pn))
+}
+func (d Delivery) Update(state uint64) {
+ C.pn_delivery_update(d.pn, C.uint64_t(state))
+}
+func (d Delivery) Clear() {
+ C.pn_delivery_clear(d.pn)
+}
+func (d Delivery) Current() bool {
+ return bool(C.pn_delivery_current(d.pn))
+}
+func (d Delivery) Settle() {
+ C.pn_delivery_settle(d.pn)
+}
+func (d Delivery) Dump() {
+ C.pn_delivery_dump(d.pn)
+}
+func (d Delivery) Buffered() bool {
+ return bool(C.pn_delivery_buffered(d.pn))
+}
+
+// Wrappers for declarations in disposition.h
+
+type Disposition struct{ pn *C.pn_disposition_t }
+
+func (d Disposition) IsNil() bool { return d.pn == nil }
+func (d Disposition) CPtr() unsafe.Pointer { return unsafe.Pointer(d.pn) }
+func (d Disposition) Type() uint64 {
+ return uint64(C.pn_disposition_type(d.pn))
+}
+func (d Disposition) Condition() Condition {
+ return Condition{C.pn_disposition_condition(d.pn)}
+}
+func (d Disposition) Data() Data {
+ return Data{C.pn_disposition_data(d.pn)}
+}
+func (d Disposition) SectionNumber() uint16 {
+ return uint16(C.pn_disposition_get_section_number(d.pn))
+}
+func (d Disposition) SetSectionNumber(section_number uint16) {
+ C.pn_disposition_set_section_number(d.pn, C.uint32_t(section_number))
+}
+func (d Disposition) SectionOffset() uint64 {
+ return uint64(C.pn_disposition_get_section_offset(d.pn))
+}
+func (d Disposition) SetSectionOffset(section_offset uint64) {
+ C.pn_disposition_set_section_offset(d.pn, C.uint64_t(section_offset))
+}
+func (d Disposition) IsFailed() bool {
+ return bool(C.pn_disposition_is_failed(d.pn))
+}
+func (d Disposition) SetFailed(failed bool) {
+ C.pn_disposition_set_failed(d.pn, C.bool(failed))
+}
+func (d Disposition) IsUndeliverable() bool {
+ return bool(C.pn_disposition_is_undeliverable(d.pn))
+}
+func (d Disposition) SetUndeliverable(undeliverable bool) {
+ C.pn_disposition_set_undeliverable(d.pn, C.bool(undeliverable))
+}
+func (d Disposition) Annotations() Data {
+ return Data{C.pn_disposition_annotations(d.pn)}
+}
+
+// Wrappers for declarations in condition.h
+
+type Condition struct{ pn *C.pn_condition_t }
+
+func (c Condition) IsNil() bool { return c.pn == nil }
+func (c Condition) CPtr() unsafe.Pointer { return unsafe.Pointer(c.pn) }
+func (c Condition) IsSet() bool {
+ return bool(C.pn_condition_is_set(c.pn))
+}
+func (c Condition) Clear() {
+ C.pn_condition_clear(c.pn)
+}
+func (c Condition) Name() string {
+ return C.GoString(C.pn_condition_get_name(c.pn))
+}
+func (c Condition) SetName(name string) int {
+ nameC := C.CString(name)
+ defer C.free(unsafe.Pointer(nameC))
+
+ return int(C.pn_condition_set_name(c.pn, nameC))
+}
+func (c Condition) Description() string {
+ return C.GoString(C.pn_condition_get_description(c.pn))
+}
+func (c Condition) SetDescription(description string) int {
+ descriptionC := C.CString(description)
+ defer C.free(unsafe.Pointer(descriptionC))
+
+ return int(C.pn_condition_set_description(c.pn, descriptionC))
+}
+func (c Condition) Info() Data {
+ return Data{C.pn_condition_info(c.pn)}
+}
+func (c Condition) IsRedirect() bool {
+ return bool(C.pn_condition_is_redirect(c.pn))
+}
+func (c Condition) RedirectHost() string {
+ return C.GoString(C.pn_condition_redirect_host(c.pn))
+}
+func (c Condition) RedirectPort() int {
+ return int(C.pn_condition_redirect_port(c.pn))
+}
+
+// Wrappers for declarations in terminus.h
+
+type TerminusType C.pn_terminus_type_t
+
+const (
+ Unspecified TerminusType = C.PN_UNSPECIFIED
+ Source TerminusType = C.PN_SOURCE
+ Target TerminusType = C.PN_TARGET
+ Coordinator TerminusType = C.PN_COORDINATOR
+)
+
+func (e TerminusType) String() string {
+ switch e {
+
+ case C.PN_UNSPECIFIED:
+ return "Unspecified"
+ case C.PN_SOURCE:
+ return "Source"
+ case C.PN_TARGET:
+ return "Target"
+ case C.PN_COORDINATOR:
+ return "Coordinator"
+ }
+ return "unknown"
+}
+
+type Durability C.pn_durability_t
+
+const (
+ Nondurable Durability = C.PN_NONDURABLE
+ Configuration Durability = C.PN_CONFIGURATION
+ Deliveries Durability = C.PN_DELIVERIES
+)
+
+func (e Durability) String() string {
+ switch e {
+
+ case C.PN_NONDURABLE:
+ return "Nondurable"
+ case C.PN_CONFIGURATION:
+ return "Configuration"
+ case C.PN_DELIVERIES:
+ return "Deliveries"
+ }
+ return "unknown"
+}
+
+type ExpiryPolicy C.pn_expiry_policy_t
+
+const (
+ ExpireWithLink ExpiryPolicy = C.PN_EXPIRE_WITH_LINK
+ ExpireWithSession ExpiryPolicy = C.PN_EXPIRE_WITH_SESSION
+ ExpireWithConnection ExpiryPolicy = C.PN_EXPIRE_WITH_CONNECTION
+ ExpireNever ExpiryPolicy = C.PN_EXPIRE_NEVER
+)
+
+func (e ExpiryPolicy) String() string {
+ switch e {
+
+ case C.PN_EXPIRE_WITH_LINK:
+ return "ExpireWithLink"
+ case C.PN_EXPIRE_WITH_SESSION:
+ return "ExpireWithSession"
+ case C.PN_EXPIRE_WITH_CONNECTION:
+ return "ExpireWithConnection"
+ case C.PN_EXPIRE_NEVER:
+ return "ExpireNever"
+ }
+ return "unknown"
+}
+
+type DistributionMode C.pn_distribution_mode_t
+
+const (
+ DistModeUnspecified DistributionMode = C.PN_DIST_MODE_UNSPECIFIED
+ DistModeCopy DistributionMode = C.PN_DIST_MODE_COPY
+ DistModeMove DistributionMode = C.PN_DIST_MODE_MOVE
+)
+
+func (e DistributionMode) String() string {
+ switch e {
+
+ case C.PN_DIST_MODE_UNSPECIFIED:
+ return "DistModeUnspecified"
+ case C.PN_DIST_MODE_COPY:
+ return "DistModeCopy"
+ case C.PN_DIST_MODE_MOVE:
+ return "DistModeMove"
+ }
+ return "unknown"
+}
+
+type Terminus struct{ pn *C.pn_terminus_t }
+
+func (t Terminus) IsNil() bool { return t.pn == nil }
+func (t Terminus) CPtr() unsafe.Pointer { return unsafe.Pointer(t.pn) }
+func (t Terminus) Type() TerminusType {
+ return TerminusType(C.pn_terminus_get_type(t.pn))
+}
+func (t Terminus) SetType(type_ TerminusType) int {
+ return int(C.pn_terminus_set_type(t.pn, C.pn_terminus_type_t(type_)))
+}
+func (t Terminus) Address() string {
+ return C.GoString(C.pn_terminus_get_address(t.pn))
+}
+func (t Terminus) SetAddress(address string) int {
+ addressC := C.CString(address)
+ defer C.free(unsafe.Pointer(addressC))
+
+ return int(C.pn_terminus_set_address(t.pn, addressC))
+}
+func (t Terminus) SetDistributionMode(mode DistributionMode) int {
+ return int(C.pn_terminus_set_distribution_mode(t.pn, C.pn_distribution_mode_t(mode)))
+}
+func (t Terminus) Durability() Durability {
+ return Durability(C.pn_terminus_get_durability(t.pn))
+}
+func (t Terminus) SetDurability(durability Durability) int {
+ return int(C.pn_terminus_set_durability(t.pn, C.pn_durability_t(durability)))
+}
+func (t Terminus) ExpiryPolicy() ExpiryPolicy {
+ return ExpiryPolicy(C.pn_terminus_get_expiry_policy(t.pn))
+}
+func (t Terminus) SetExpiryPolicy(policy ExpiryPolicy) int {
+ return int(C.pn_terminus_set_expiry_policy(t.pn, C.pn_expiry_policy_t(policy)))
+}
+func (t Terminus) Timeout() time.Duration {
+ return (time.Duration(C.pn_terminus_get_timeout(t.pn)) * time.Second)
+}
+func (t Terminus) SetTimeout(timeout time.Duration) int {
- return int(C.pn_terminus_set_timeout(t.pn, C.pn_seconds_t(timeout)))
++ return int(C.pn_terminus_set_timeout(t.pn, C.pn_seconds_t(timeout/time.Second)))
+}
+func (t Terminus) IsDynamic() bool {
+ return bool(C.pn_terminus_is_dynamic(t.pn))
+}
+func (t Terminus) SetDynamic(dynamic bool) int {
+ return int(C.pn_terminus_set_dynamic(t.pn, C.bool(dynamic)))
+}
+func (t Terminus) Properties() Data {
+ return Data{C.pn_terminus_properties(t.pn)}
+}
+func (t Terminus) Capabilities() Data {
+ return Data{C.pn_terminus_capabilities(t.pn)}
+}
+func (t Terminus) Outcomes() Data {
+ return Data{C.pn_terminus_outcomes(t.pn)}
+}
+func (t Terminus) Filter() Data {
+ return Data{C.pn_terminus_filter(t.pn)}
+}
+func (t Terminus) Copy(src Terminus) int {
+ return int(C.pn_terminus_copy(t.pn, src.pn))
+}
+
+// Wrappers for declarations in connection.h
+
+type Connection struct{ pn *C.pn_connection_t }
+
+func (c Connection) IsNil() bool { return c.pn == nil }
+func (c Connection) CPtr() unsafe.Pointer { return unsafe.Pointer(c.pn) }
+func (c Connection) Free() {
+ C.pn_connection_free(c.pn)
+}
+func (c Connection) Release() {
+ C.pn_connection_release(c.pn)
+}
+func (c Connection) Error() error {
+ return PnError(C.pn_connection_error(c.pn))
+}
+func (c Connection) State() State {
+ return State(C.pn_connection_state(c.pn))
+}
+func (c Connection) Open() {
+ C.pn_connection_open(c.pn)
+}
+func (c Connection) Close() {
+ C.pn_connection_close(c.pn)
+}
+func (c Connection) Reset() {
+ C.pn_connection_reset(c.pn)
+}
+func (c Connection) Condition() Condition {
+ return Condition{C.pn_connection_condition(c.pn)}
+}
+func (c Connection) RemoteCondition() Condition {
+ return Condition{C.pn_connection_remote_condition(c.pn)}
+}
+func (c Connection) Container() string {
+ return C.GoString(C.pn_connection_get_container(c.pn))
+}
+func (c Connection) SetContainer(container string) {
+ containerC := C.CString(container)
+ defer C.free(unsafe.Pointer(containerC))
+
+ C.pn_connection_set_container(c.pn, containerC)
+}
+func (c Connection) SetUser(user string) {
+ userC := C.CString(user)
+ defer C.free(unsafe.Pointer(userC))
+
+ C.pn_connection_set_user(c.pn, userC)
+}
+func (c Connection) User() string {
+ return C.GoString(C.pn_connection_get_user(c.pn))
+}
+func (c Connection) Hostname() string {
+ return C.GoString(C.pn_connection_get_hostname(c.pn))
+}
+func (c Connection) SetHostname(hostname string) {
+ hostnameC := C.CString(hostname)
+ defer C.free(unsafe.Pointer(hostnameC))
+
+ C.pn_connection_set_hostname(c.pn, hostnameC)
+}
+func (c Connection) RemoteContainer() string {
+ return C.GoString(C.pn_connection_remote_container(c.pn))
+}
+func (c Connection) RemoteHostname() string {
+ return C.GoString(C.pn_connection_remote_hostname(c.pn))
+}
+func (c Connection) OfferedCapabilities() Data {
+ return Data{C.pn_connection_offered_capabilities(c.pn)}
+}
+func (c Connection) DesiredCapabilities() Data {
+ return Data{C.pn_connection_desired_capabilities(c.pn)}
+}
+func (c Connection) Properties() Data {
+ return Data{C.pn_connection_properties(c.pn)}
+}
+func (c Connection) RemoteOfferedCapabilities() Data {
+ return Data{C.pn_connection_remote_offered_capabilities(c.pn)}
+}
+func (c Connection) RemoteDesiredCapabilities() Data {
+ return Data{C.pn_connection_remote_desired_capabilities(c.pn)}
+}
+func (c Connection) RemoteProperties() Data {
+ return Data{C.pn_connection_remote_properties(c.pn)}
+}
+func (c Connection) Transport() Transport {
+ return Transport{C.pn_connection_transport(c.pn)}
+}
+
+// Wrappers for declarations in transport.h
+
+type Transport struct{ pn *C.pn_transport_t }
+
+func (t Transport) IsNil() bool { return t.pn == nil }
+func (t Transport) CPtr() unsafe.Pointer { return unsafe.Pointer(t.pn) }
+func (t Transport) SetServer() {
+ C.pn_transport_set_server(t.pn)
+}
+func (t Transport) Free() {
+ C.pn_transport_free(t.pn)
+}
+func (t Transport) User() string {
+ return C.GoString(C.pn_transport_get_user(t.pn))
+}
+func (t Transport) RequireAuth(required bool) {
+ C.pn_transport_require_auth(t.pn, C.bool(required))
+}
+func (t Transport) IsAuthenticated() bool {
+ return bool(C.pn_transport_is_authenticated(t.pn))
+}
+func (t Transport) RequireEncryption(required bool) {
+ C.pn_transport_require_encryption(t.pn, C.bool(required))
+}
+func (t Transport) IsEncrypted() bool {
+ return bool(C.pn_transport_is_encrypted(t.pn))
+}
+func (t Transport) Condition() Condition {
+ return Condition{C.pn_transport_condition(t.pn)}
+}
+func (t Transport) Error() error {
+ return PnError(C.pn_transport_error(t.pn))
+}
+func (t Transport) Bind(connection Connection) int {
+ return int(C.pn_transport_bind(t.pn, connection.pn))
+}
+func (t Transport) Unbind() int {
+ return int(C.pn_transport_unbind(t.pn))
+}
+func (t Transport) Log(message string) {
+ messageC := C.CString(message)
+ defer C.free(unsafe.Pointer(messageC))
+
+ C.pn_transport_log(t.pn, messageC)
+}
+func (t Transport) ChannelMax() uint32 {
+ return uint32(C.pn_transport_get_channel_max(t.pn))
+}
+func (t Transport) SetChannelMax(channel_max uint32) int {
+ return int(C.pn_transport_set_channel_max(t.pn, C.uint16_t(channel_max)))
+}
+func (t Transport) RemoteChannelMax() uint32 {
+ return uint32(C.pn_transport_remote_channel_max(t.pn))
+}
+func (t Transport) MaxFrame() uint16 {
+ return uint16(C.pn_transport_get_max_frame(t.pn))
+}
+func (t Transport) SetMaxFrame(size uint16) {
+ C.pn_transport_set_max_frame(t.pn, C.uint32_t(size))
+}
+func (t Transport) RemoteMaxFrame() uint16 {
+ return uint16(C.pn_transport_get_remote_max_frame(t.pn))
+}
+func (t Transport) IdleTimeout() time.Duration {
+ return (time.Duration(C.pn_transport_get_idle_timeout(t.pn)) * time.Millisecond)
+}
+func (t Transport) SetIdleTimeout(timeout time.Duration) {
+ C.pn_transport_set_idle_timeout(t.pn, C.pn_millis_t(timeout/time.Millisecond))
+}
+func (t Transport) RemoteIdleTimeout() time.Duration {
+ return (time.Duration(C.pn_transport_get_remote_idle_timeout(t.pn)) * time.Millisecond)
+}
+func (t Transport) Input(bytes string, available uint) int {
+ bytesC := C.CString(bytes)
+ defer C.free(unsafe.Pointer(bytesC))
+
+ return int(C.pn_transport_input(t.pn, bytesC, C.size_t(available)))
+}
+func (t Transport) Output(bytes string, size uint) int {
+ bytesC := C.CString(bytes)
+ defer C.free(unsafe.Pointer(bytesC))
+
+ return int(C.pn_transport_output(t.pn, bytesC, C.size_t(size)))
+}
+func (t Transport) Capacity() int {
+ return int(C.pn_transport_capacity(t.pn))
+}
+func (t Transport) Process(size uint) int {
+ return int(C.pn_transport_process(t.pn, C.size_t(size)))
+}
+func (t Transport) CloseTail() int {
+ return int(C.pn_transport_close_tail(t.pn))
+}
+func (t Transport) Pending() int {
+ return int(C.pn_transport_pending(t.pn))
+}
+func (t Transport) Peek(dst string, size uint) int {
+ dstC := C.CString(dst)
+ defer C.free(unsafe.Pointer(dstC))
+
+ return int(C.pn_transport_peek(t.pn, dstC, C.size_t(size)))
+}
+func (t Transport) Pop(size uint) {
+ C.pn_transport_pop(t.pn, C.size_t(size))
+}
+func (t Transport) CloseHead() int {
+ return int(C.pn_transport_close_head(t.pn))
+}
+func (t Transport) Quiesced() bool {
+ return bool(C.pn_transport_quiesced(t.pn))
+}
+func (t Transport) Closed() bool {
+ return bool(C.pn_transport_closed(t.pn))
+}
+func (t Transport) Tick(now time.Time) time.Time {
+ return goTime(C.pn_transport_tick(t.pn, pnTime(now)))
+}
+func (t Transport) Connection() Connection {
+ return Connection{C.pn_transport_connection(t.pn)}
+}
+
+// Wrappers for declarations in sasl.h
+
+type SASLOutcome C.pn_sasl_outcome_t
+
+const (
+ SASLNone SASLOutcome = C.PN_SASL_NONE
+ SASLOk SASLOutcome = C.PN_SASL_OK
+ SASLAuth SASLOutcome = C.PN_SASL_AUTH
+ SASLSys SASLOutcome = C.PN_SASL_SYS
+ SASLPerm SASLOutcome = C.PN_SASL_PERM
+ SASLTemp SASLOutcome = C.PN_SASL_TEMP
+)
+
+func (e SASLOutcome) String() string {
+ switch e {
+
+ case C.PN_SASL_NONE:
+ return "SASLNone"
+ case C.PN_SASL_OK:
+ return "SASLOk"
+ case C.PN_SASL_AUTH:
+ return "SASLAuth"
+ case C.PN_SASL_SYS:
+ return "SASLSys"
+ case C.PN_SASL_PERM:
+ return "SASLPerm"
+ case C.PN_SASL_TEMP:
+ return "SASLTemp"
+ }
+ return "unknown"
+}
+
+type SASL struct{ pn *C.pn_sasl_t }
+
+func (s SASL) IsNil() bool { return s.pn == nil }
+func (s SASL) CPtr() unsafe.Pointer { return unsafe.Pointer(s.pn) }
+func (s SASL) Done(outcome SASLOutcome) {
+ C.pn_sasl_done(s.pn, C.pn_sasl_outcome_t(outcome))
+}
+func (s SASL) Outcome() SASLOutcome {
+ return SASLOutcome(C.pn_sasl_outcome(s.pn))
+}
+func (s SASL) User() string {
+ return C.GoString(C.pn_sasl_get_user(s.pn))
+}
+func (s SASL) Mech() string {
+ return C.GoString(C.pn_sasl_get_mech(s.pn))
+}
+func (s SASL) AllowedMechs(mechs string) {
+ mechsC := C.CString(mechs)
+ defer C.free(unsafe.Pointer(mechsC))
+
+ C.pn_sasl_allowed_mechs(s.pn, mechsC)
+}
+func (s SASL) SetAllowInsecureMechs(insecure bool) {
+ C.pn_sasl_set_allow_insecure_mechs(s.pn, C.bool(insecure))
+}
+func (s SASL) AllowInsecureMechs() bool {
+ return bool(C.pn_sasl_get_allow_insecure_mechs(s.pn))
+}
+func (s SASL) ConfigName(name string) {
+ nameC := C.CString(name)
+ defer C.free(unsafe.Pointer(nameC))
+
+ C.pn_sasl_config_name(s.pn, nameC)
+}
+func (s SASL) ConfigPath(path string) {
+ pathC := C.CString(path)
+ defer C.free(unsafe.Pointer(pathC))
+
+ C.pn_sasl_config_path(s.pn, pathC)
+}
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/569b4fca/readme-go-get.md
----------------------------------------------------------------------
diff --cc readme-go-get.md
index 6eb1e2b,0000000..c59561f
mode 100644,000000..100644
--- a/readme-go-get.md
+++ b/readme-go-get.md
@@@ -1,18 -1,0 +1,19 @@@
+The go-only subtree of proton is maintained on the branch `go1` for the `go get`
+command. `go1` is special to the `go get` command, it will use that branch
+rather than `master` when it is present.
+
+Created with:
+
+ git subtree split --prefix=proton-c/bindings/go/src/qpid.apache.org -b go1
+
+Update with:
+
+ git checkout go1
++ git pull
+ git merge -s recursive -Xsubtree=proton-c/bindings/go/src/qpid.apache.org master
+
+To see the branch description: `git config branch.go1.description`
+
+NOTE: when updating the branch, you should also visit the doc pages at
+https://godoc.org/?q=qpid.apache.org and click "Refresh now" at the bottom of
+the page
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org