You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2025/03/04 21:31:40 UTC
(qpid-proton) 03/06: PROTON-2873: Add new C APIs for different disposition types
This is an automated email from the ASF dual-hosted git repository.
astitcher pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git
commit 2f6350993289699b86f31316b344eb84959fd736
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Tue Aug 13 14:05:03 2024 -0400
PROTON-2873: Add new C APIs for different disposition types
Change the disposition representation to be a union and add APIs to
access the various disposition types and their properties.
---
c/include/proton/disposition.h | 192 +++++++++++++++++++++++++++++++++++++++++
c/src/core/engine-internal.h | 18 ++--
c/src/core/engine.c | 106 +++++++++++++++++++++++
python/cproton.h | 49 +++++++----
python/cproton.py | 19 +++-
5 files changed, 359 insertions(+), 25 deletions(-)
diff --git a/c/include/proton/disposition.h b/c/include/proton/disposition.h
index e80bf8ffd..d809b2100 100644
--- a/c/include/proton/disposition.h
+++ b/c/include/proton/disposition.h
@@ -227,6 +227,198 @@ PN_EXTERN void pn_disposition_set_undeliverable(pn_disposition_t *disposition, b
*/
PN_EXTERN pn_data_t *pn_disposition_annotations(pn_disposition_t *disposition);
+/**
+ * A received delivery disposition
+ *
+ * This represents the non terminal delivery received state.
+ */
+typedef struct pn_received_disposition_t pn_received_disposition_t;
+
+/**
+ * A rejected delivery disposition
+ *
+ * This represents the terminal delivery rejected state.
+ */
+typedef struct pn_rejected_disposition_t pn_rejected_disposition_t;
+
+/**
+ * A modified delivery disposition
+ *
+ * This represents the terminal delivery modified state.
+ */
+typedef struct pn_modified_disposition_t pn_modified_disposition_t;
+
+/**
+ * A custom delivery disposition
+ *
+ * This can be used to represent a disposition that is not one of the predefined
+ * AMQP delivery dispositions.
+ */
+typedef struct pn_custom_disposition_t pn_custom_disposition_t;
+
+/**
+ * Convert a delivery disposition to a custom disposition
+ *
+ * @param[in] disposition delivery disposition object
+ * @return a pointer to the equivalent custom disposition type
+ */
+PN_EXTERN pn_custom_disposition_t *pn_custom_disposition(pn_disposition_t *disposition);
+
+/**
+ * Convert a delivery disposition to a received disposition
+ *
+ * @param[in] disposition delivery disposition object
+ * @return a pointer to the received disposition or NULL
+ * if the disposition is not that type
+ */
+PN_EXTERN pn_received_disposition_t *pn_received_disposition(pn_disposition_t *disposition);
+
+/**
+ * Convert a delivery disposition to a rejected disposition
+ *
+ * @param[in] disposition delivery disposition object
+ * @return a pointer to the rejected disposition or NULL
+ * if the disposition is not that type
+ */
+PN_EXTERN pn_rejected_disposition_t *pn_rejected_disposition(pn_disposition_t *disposition);
+
+/**
+ * Convert a delivery disposition to a modified disposition
+ *
+ * @param[in] disposition delivery disposition object
+ * @return a pointer to the modified disposition or NULL
+ * if the disposition is not that type
+ */
+PN_EXTERN pn_modified_disposition_t *pn_modified_disposition(pn_disposition_t *disposition);
+
+/**
+ * Access the disposition as a raw pn_data_t.
+ *
+ * Dispositions are an extension point in the AMQP protocol. The
+ * disposition interface provides setters/getters for those
+ * dispositions that are predefined by the specification, however
+ * access to the raw disposition data is provided so that other
+ * dispositions can be used.
+ *
+ * The ::pn_data_t pointer returned by this operation is valid until
+ * the parent delivery is settled.
+ *
+ * @param[in] disposition a custom disposition object
+ * @return a pointer to the raw disposition data
+ */
+PN_EXTERN pn_data_t *pn_custom_disposition_data(pn_custom_disposition_t *disposition);
+
+/**
+ * Get the type of a custom disposition.
+ *
+ * @param[in] disposition a custom disposition object
+ * @return the type of the disposition
+ */
+PN_EXTERN uint64_t pn_custom_disposition_get_type(pn_custom_disposition_t *disposition);
+
+/**
+ * Set the type of a custom disposition.
+ *
+ * @param[in] disposition a custom disposition object
+ * @param[in] type the type of the disposition
+ */
+PN_EXTERN void pn_custom_disposition_set_type(pn_custom_disposition_t *disposition, uint64_t type);
+
+/**
+ * Access the condition object associated with a rejected disposition.
+ *
+ * The ::pn_condition_t object retrieved by this operation may be
+ * modified prior to updating a delivery. When a delivery is updated,
+ * the condition described by the disposition is reported to the peer.
+ *
+ * The pointer returned by this operation is valid until the parent
+ * delivery is settled.
+ *
+ * @param[in] disposition a disposition object
+ * @return a pointer to the disposition condition
+ */
+PN_EXTERN pn_condition_t *pn_rejected_disposition_condition(pn_rejected_disposition_t *disposition);
+
+/**
+ * Get the section number associated with a received disposition.
+ *
+ * @param[in] disposition a disposition object
+ * @return a section number
+ */
+PN_EXTERN uint32_t pn_received_disposition_get_section_number(pn_received_disposition_t *disposition);
+
+/**
+ * Set the section number associated with a received disposition.
+ *
+ * @param[in] disposition a disposition object
+ * @param[in] section_number a section number
+ */
+PN_EXTERN void pn_received_disposition_set_section_number(pn_received_disposition_t *disposition, uint32_t section_number);
+
+/**
+ * Get the section offset associated with a received disposition.
+ *
+ * @param[in] disposition a disposition object
+ * @return a section offset
+ */
+PN_EXTERN uint64_t pn_received_disposition_get_section_offset(pn_received_disposition_t *disposition);
+
+/**
+ * Set the section offset associated with a received disposition.
+ *
+ * @param[in] disposition a disposition object
+ * @param[in] section_offset a section offset
+ */
+PN_EXTERN void pn_received_disposition_set_section_offset(pn_received_disposition_t *disposition, uint64_t section_offset);
+
+/**
+ * Check if a modified disposition has the failed flag set.
+ *
+ * @param[in] disposition a disposition object
+ * @return true if the disposition has the failed flag set, false otherwise
+ */
+PN_EXTERN bool pn_modified_disposition_is_failed(pn_modified_disposition_t *disposition);
+
+/**
+ * Set the failed flag on a modified disposition.
+ *
+ * @param[in] disposition a disposition object
+ * @param[in] failed the value of the failed flag
+ */
+PN_EXTERN void pn_modified_disposition_set_failed(pn_modified_disposition_t *disposition, bool failed);
+
+/**
+ * Check if a modified disposition has the undeliverable flag set.
+ *
+ * @param[in] disposition a disposition object
+ * @return true if the disposition has the undeliverable flag set, false otherwise
+ */
+PN_EXTERN bool pn_modified_disposition_is_undeliverable(pn_modified_disposition_t *disposition);
+
+/**
+ * Set the undeliverable flag on a modified disposition.
+ *
+ * @param[in] disposition a disposition object
+ * @param[in] undeliverable the value of the undeliverable flag
+ */
+PN_EXTERN void pn_modified_disposition_set_undeliverable(pn_modified_disposition_t *disposition, bool undeliverable);
+
+/**
+ * Access the annotations associated with a modified disposition.
+ *
+ * The ::pn_data_t object retrieved by this operation may be modified
+ * prior to updating a delivery. When a delivery is updated, the
+ * annotations described by the ::pn_data_t are reported to the peer.
+ * The ::pn_data_t must be empty or contain a symbol keyed map.
+ *
+ * The pointer returned by this operation is valid until the parent
+ * delivery is settled.
+ *
+ * @param[in] disposition a disposition object
+ * @return the annotations associated with the disposition
+ */
+PN_EXTERN pn_data_t *pn_modified_disposition_annotations(pn_modified_disposition_t *disposition);
+
/**
* @}
*/
diff --git a/c/src/core/engine-internal.h b/c/src/core/engine-internal.h
index e0e588b58..da563813a 100644
--- a/c/src/core/engine-internal.h
+++ b/c/src/core/engine-internal.h
@@ -343,27 +343,27 @@ typedef enum pn_disposition_type_t {
PN_DISP_MODIFIED = PN_MODIFIED,
} pn_disposition_type_t;
-typedef struct pn_received_disposition_t {
+struct pn_received_disposition_t {
uint64_t section_offset;
uint32_t section_number;
-} pn_received_disposition_t;
+};
-typedef struct pn_rejected_disposition_t {
+struct pn_rejected_disposition_t {
pn_condition_t condition;
-} pn_rejected_disposition_t;
+};
-typedef struct pn_modified_disposition_t {
+struct pn_modified_disposition_t {
pn_data_t *annotations;
pn_bytes_t annotations_raw;
bool failed;
bool undeliverable;
-} pn_modified_disposition_t;
+};
-typedef struct pn_custom_disposition_t {
+struct pn_custom_disposition_t {
pn_data_t *data;
- uint64_t type;
pn_bytes_t data_raw;
-} pn_custom_disposition_t;
+ uint64_t type;
+};
struct pn_disposition_t {
union {
diff --git a/c/src/core/engine.c b/c/src/core/engine.c
index ad9e77fd5..7ccb308b9 100644
--- a/c/src/core/engine.c
+++ b/c/src/core/engine.c
@@ -1978,6 +1978,112 @@ pn_condition_t *pn_disposition_condition(pn_disposition_t *disposition)
return &disposition->u.s_rejected.condition;
}
+pn_custom_disposition_t *pn_custom_disposition(pn_disposition_t *disposition)
+{
+ pni_disposition_to_raw(disposition);
+ return &disposition->u.s_custom;
+}
+
+pn_received_disposition_t *pn_received_disposition(pn_disposition_t *disposition)
+{
+ if (disposition->type==PN_DISP_EMPTY) disposition->type = PN_DISP_RECEIVED;
+ else if (disposition->type!=PN_DISP_RECEIVED) return NULL;
+ return &disposition->u.s_received;
+}
+
+pn_rejected_disposition_t *pn_rejected_disposition(pn_disposition_t *disposition)
+{
+ if (disposition->type==PN_DISP_EMPTY) disposition->type = PN_DISP_REJECTED;
+ else if (disposition->type!=PN_DISP_REJECTED) return NULL;
+ return &disposition->u.s_rejected;
+}
+
+pn_modified_disposition_t *pn_modified_disposition(pn_disposition_t *disposition)
+{
+ if (disposition->type==PN_DISP_EMPTY) disposition->type = PN_DISP_MODIFIED;
+ else if (disposition->type!=PN_DISP_MODIFIED) return NULL;
+ return &disposition->u.s_modified;
+}
+
+pn_data_t *pn_custom_disposition_data(pn_custom_disposition_t *disposition)
+{
+ assert(disposition);
+ pni_switch_to_data(&disposition->data_raw, &disposition->data);
+ return disposition->data;
+}
+
+uint64_t pn_custom_disposition_get_type(pn_custom_disposition_t *disposition)
+{
+ assert(disposition);
+ return disposition->type;
+}
+
+void pn_custom_disposition_set_type(pn_custom_disposition_t *disposition, uint64_t type)
+{
+ assert(disposition);
+ disposition->type = type;
+}
+
+pn_condition_t *pn_rejected_disposition_condition(pn_rejected_disposition_t *disposition)
+{
+ assert(disposition);
+ return &disposition->condition;
+}
+
+uint32_t pn_received_disposition_get_section_number(pn_received_disposition_t *disposition)
+{
+ assert(disposition);
+ return disposition->section_number;
+}
+
+void pn_received_disposition_set_section_number(pn_received_disposition_t *disposition, uint32_t section_number)
+{
+ assert(disposition);
+ disposition->section_number = section_number;
+}
+
+uint64_t pn_received_disposition_get_section_offset(pn_received_disposition_t *disposition)
+{
+ assert(disposition);
+ return disposition->section_offset;
+}
+
+void pn_received_disposition_set_section_offset(pn_received_disposition_t *disposition, uint64_t section_offset)
+{
+ assert(disposition);
+ disposition->section_offset = section_offset;
+}
+
+bool pn_modified_disposition_is_failed(pn_modified_disposition_t *disposition) {
+ assert(disposition);
+ return disposition->failed;
+}
+
+void pn_modified_disposition_set_failed(pn_modified_disposition_t *disposition, bool failed)
+{
+ assert(disposition);
+ disposition->failed = failed;
+}
+
+bool pn_modified_disposition_is_undeliverable(pn_modified_disposition_t *disposition)
+{
+ assert(disposition);
+ return disposition->undeliverable;
+}
+
+void pn_modified_disposition_set_undeliverable(pn_modified_disposition_t *disposition, bool undeliverable)
+{
+ assert(disposition);
+ disposition->undeliverable = undeliverable;
+}
+
+pn_data_t *pn_modified_disposition_annotations(pn_modified_disposition_t *disposition)
+{
+ assert(disposition);
+ pni_switch_to_data(&disposition->annotations_raw, &disposition->annotations);
+ return disposition->annotations;
+}
+
pn_delivery_tag_t pn_delivery_tag(pn_delivery_t *delivery)
{
if (delivery) {
diff --git a/python/cproton.h b/python/cproton.h
index 29dc30ba4..f98915693 100644
--- a/python/cproton.h
+++ b/python/cproton.h
@@ -29,7 +29,7 @@ typedef struct pn_collector_t pn_collector_t;
typedef struct pn_condition_t pn_condition_t;
typedef struct pn_connection_t pn_connection_t;
typedef struct pn_data_t pn_data_t;
-typedef struct
+typedef struct
{
char bytes[16];
} pn_decimal128_t;
@@ -38,13 +38,13 @@ typedef uint64_t pn_decimal64_t;
typedef struct pn_delivery_t pn_delivery_t;
typedef pn_bytes_t pn_delivery_tag_t;
typedef struct pn_disposition_t pn_disposition_t;
-typedef enum
+typedef enum
{
PN_DIST_MODE_UNSPECIFIED = 0,
PN_DIST_MODE_COPY = 1,
PN_DIST_MODE_MOVE = 2
} pn_distribution_mode_t;
-typedef enum
+typedef enum
{
PN_NONDURABLE = 0,
PN_CONFIGURATION = 1,
@@ -52,7 +52,7 @@ typedef enum
} pn_durability_t;
typedef struct pn_error_t pn_error_t;
typedef struct pn_event_t pn_event_t;
-typedef enum
+typedef enum
{
PN_EVENT_NONE = 0,
PN_REACTOR_INIT,
@@ -114,7 +114,7 @@ typedef enum
PN_RAW_CONNECTION_WAKE,
PN_RAW_CONNECTION_DRAIN_BUFFERS
} pn_event_type_t;
-typedef enum
+typedef enum
{
PN_EXPIRE_WITH_LINK,
PN_EXPIRE_WITH_SESSION,
@@ -130,7 +130,7 @@ typedef enum
PN_RCV_SECOND = 1
} pn_rcv_settle_mode_t;
typedef struct pn_record_t pn_record_t;
-typedef enum
+typedef enum
{
PN_SASL_NONE = -1,
PN_SASL_OK = 0,
@@ -143,13 +143,13 @@ typedef struct pn_sasl_t pn_sasl_t;
typedef uint32_t pn_seconds_t;
typedef uint32_t pn_sequence_t;
typedef struct pn_session_t pn_session_t;
-typedef enum
+typedef enum
{
PN_SND_UNSETTLED = 0,
PN_SND_SETTLED = 1,
PN_SND_MIXED = 2
} pn_snd_settle_mode_t;
-typedef enum
+typedef enum
{
PN_SSL_CERT_SUBJECT_COUNTRY_NAME,
PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE,
@@ -159,26 +159,26 @@ typedef enum
PN_SSL_CERT_SUBJECT_COMMON_NAME
} pn_ssl_cert_subject_subfield;
typedef struct pn_ssl_domain_t pn_ssl_domain_t;
-typedef enum
+typedef enum
{
PN_SSL_SHA1,
PN_SSL_SHA256,
PN_SSL_SHA512,
PN_SSL_MD5
} pn_ssl_hash_alg;
-typedef enum
+typedef enum
{
PN_SSL_MODE_CLIENT = 1,
PN_SSL_MODE_SERVER
} pn_ssl_mode_t;
-typedef enum
+typedef enum
{
PN_SSL_RESUME_UNKNOWN,
PN_SSL_RESUME_NEW,
PN_SSL_RESUME_REUSED
} pn_ssl_resume_status_t;
typedef struct pn_ssl_t pn_ssl_t;
-typedef enum
+typedef enum
{
PN_SSL_VERIFY_NULL = 0,
PN_SSL_VERIFY_PEER,
@@ -187,7 +187,7 @@ typedef enum
} pn_ssl_verify_mode_t;
typedef int pn_state_t;
typedef struct pn_terminus_t pn_terminus_t;
-typedef enum
+typedef enum
{
PN_UNSPECIFIED = 0,
PN_SOURCE = 1,
@@ -197,7 +197,7 @@ typedef enum
typedef int64_t pn_timestamp_t;
typedef int pn_trace_t;
typedef struct pn_transport_t pn_transport_t;
-typedef enum
+typedef enum
{
PN_NULL = 1,
PN_BOOL = 2,
@@ -226,7 +226,7 @@ typedef enum
PN_MAP = 25,
PN_INVALID = -1
} pn_type_t;
-typedef struct
+typedef struct
{
char bytes[16];
} pn_uuid_t;
@@ -406,6 +406,25 @@ void pn_disposition_set_section_offset(pn_disposition_t *disposition, uint64_t s
void pn_disposition_set_undeliverable(pn_disposition_t *disposition, _Bool undeliverable);
uint64_t pn_disposition_type(pn_disposition_t *disposition);
+typedef struct pn_received_disposition_t pn_received_disposition_t;
+typedef struct pn_rejected_disposition_t pn_rejected_disposition_t;
+typedef struct pn_modified_disposition_t pn_modified_disposition_t;
+
+pn_received_disposition_t *pn_received_disposition(pn_disposition_t *disposition);
+pn_rejected_disposition_t *pn_rejected_disposition(pn_disposition_t *disposition);
+pn_modified_disposition_t *pn_modified_disposition(pn_disposition_t *disposition);
+
+pn_condition_t *pn_rejected_disposition_condition(pn_rejected_disposition_t *disposition);
+uint32_t pn_received_disposition_get_section_number(pn_received_disposition_t *disposition);
+void pn_received_disposition_set_section_number(pn_received_disposition_t *disposition, uint32_t section_number);
+uint64_t pn_received_disposition_get_section_offset(pn_received_disposition_t *disposition);
+void pn_received_disposition_set_section_offset(pn_received_disposition_t *disposition, uint64_t section_offset);
+_Bool pn_modified_disposition_is_failed(pn_modified_disposition_t *disposition);
+void pn_modified_disposition_set_failed(pn_modified_disposition_t *disposition, _Bool failed);
+_Bool pn_modified_disposition_is_undeliverable(pn_modified_disposition_t *disposition);
+void pn_modified_disposition_set_undeliverable(pn_modified_disposition_t *disposition, _Bool undeliverable);
+pn_data_t *pn_modified_disposition_annotations(pn_modified_disposition_t *disposition);
+
int pn_error_code(pn_error_t *error);
const char *pn_error_text(pn_error_t *error);
diff --git a/python/cproton.py b/python/cproton.py
index 6be8711d8..1dea17ac1 100644
--- a/python/cproton.py
+++ b/python/cproton.py
@@ -158,7 +158,24 @@ from cproton_ffi.lib import (PN_ACCEPTED, PN_ARRAY, PN_BINARY, PN_BOOL, PN_BYTE,
pn_transport_require_encryption, pn_transport_set_channel_max,
pn_transport_set_idle_timeout, pn_transport_set_max_frame,
pn_transport_set_server, pn_transport_tick, pn_transport_trace,
- pn_transport_unbind)
+ pn_transport_unbind,
+ pn_custom_disposition,
+ pn_custom_disposition_get_type,
+ pn_custom_disposition_set_type,
+ pn_custom_disposition_data,
+ pn_rejected_disposition,
+ pn_rejected_disposition_condition,
+ pn_received_disposition,
+ pn_received_disposition_get_section_number,
+ pn_received_disposition_set_section_number,
+ pn_received_disposition_get_section_offset,
+ pn_received_disposition_set_section_offset,
+ pn_modified_disposition,
+ pn_modified_disposition_is_failed,
+ pn_modified_disposition_set_failed,
+ pn_modified_disposition_is_undeliverable,
+ pn_modified_disposition_set_undeliverable,
+ pn_modified_disposition_annotations)
def isnull(obj):
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org