1 /*
2  * hunt-amqp: AMQP library for D programming language, based on hunt-net.
3  *
4  * Copyright (C) 2018-2019 HuntLabs
5  *
6  * Website: https://www.huntlabs.net
7  *
8  * Licensed under the Apache-2.0 License.
9  *
10  */
11 module hunt.amqp.ProtonHelper;
12 
13 import hunt.amqp.ProtonDelivery;
14 
15 import hunt.proton.Proton;
16 import hunt.proton.amqp.Symbol;
17 import hunt.proton.amqp.messaging.Accepted;
18 import hunt.proton.amqp.messaging.AmqpValue;
19 import hunt.proton.amqp.messaging.Modified;
20 import hunt.proton.amqp.messaging.Rejected;
21 import hunt.proton.amqp.messaging.Released;
22 import hunt.proton.amqp.transport.ErrorCondition;
23 import hunt.proton.message.Message;
24 
25 import hunt.net.AsyncResult;
26 import hunt.String;
27 import hunt.Boolean;
28 
29 /**
30  * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
31  */
32 interface ProtonHelper {
33 
34     /**
35      * Creates a bare Message object.
36      *
37      * @return the message
38      */
39     static Message message() {
40         return Proton.message();
41     }
42 
43     /**
44      * Creates a Message object with the given String contained as an AmqpValue body.
45      *
46      * @param body
47      *          the string to set as an AmqpValue body
48      * @return the message
49      */
50     static Message message(String bd) {
51         Message value = message();
52         value.setBody(new AmqpValue(bd));
53         return value;
54     }
55 
56     /**
57      * Creates a Message object with the given String contained as an AmqpValue body, and the 'to' address set as given.
58      *
59      * @param address
60      *          the 'to' address to set
61      * @param body
62      *          the string to set as an AmqpValue body
63      * @return the message
64      */
65     static Message message(String address, String bd) {
66         Message value = message(bd);
67         value.setAddress(address);
68         return value;
69     }
70 
71     /**
72      * Create an ErrorCondition with the given error condition value and error description string.
73      *
74      * See the AMQP specification
75      * <a href="http://docs.oasis-open.org/amqp/core/v1.0/os/amqp-core-transport-v1.0-os.html#type-amqp-error">error
76      * sections</a> for details of various standard error condition values.
77      *
78      * For useful condition value constants, see {@link hunt.proton.amqp.transport.AmqpError AmqpError},
79      * {@link hunt.proton.amqp.transport.ConnectionError ConnectionError},
80      * {@link hunt.proton.amqp.transport.SessionError SessionError} and
81      * {@link hunt.proton.amqp.transport.LinkError LinkError}.
82      *
83      * @param condition
84      *          the error condition value
85      * @param description
86      *          String description of the error, may be null
87      * @return the condition
88      */
89     static ErrorCondition condition(Symbol condition, String description) {
90         return new ErrorCondition(condition, description);
91     }
92 
93     /**
94      * Create an ErrorCondition with the given error condition value (which will be converted to the required Symbol type)
95      * and error description string.
96      *
97      * See {@link #condition(Symbol, String)} for more details.
98      *
99      * @param condition
100      *          the error condition value, to be converted to a Symbol
101      * @param description
102      *          String description of the error, may be null
103      * @return the condition
104      */
105     static ErrorCondition condition(String condition, String description) {
106         return ProtonHelper.condition(Symbol.valueOf((cast(string)(condition.getBytes()))),
107                 description);
108     }
109 
110     /**
111      * Creates a byte[] for use as a delivery tag by UTF-8 converting the given string.
112      *
113      * @param tag
114      *          the string to convert
115      * @return byte[] for use as tag
116      */
117     static byte[] tag(String tag) {
118         return tag.getBytes();
119     }
120 
121     /**
122      * Accept the given delivery by applying Accepted disposition state, and optionally settling.
123      *
124      * @param delivery
125      *          the delivery to update
126      * @param settle
127      *          whether to settle
128      * @return the delivery
129      */
130     static ProtonDelivery accepted(ProtonDelivery delivery, bool settle) {
131         delivery.disposition(Accepted.getInstance(), settle);
132         return delivery;
133     }
134 
135     /**
136      * Reject the given delivery by applying Rejected disposition state, and optionally settling.
137      *
138      * @param delivery
139      *          the delivery to update
140      * @param settle
141      *          whether to settle
142      * @return the delivery
143      */
144     static ProtonDelivery rejected(ProtonDelivery delivery, bool settle) {
145         delivery.disposition(new Rejected(), settle);
146         return delivery;
147     }
148 
149     /**
150      * Release the given delivery by applying Released disposition state, and optionally settling.
151      *
152      * @param delivery
153      *          the delivery to update
154      * @param settle
155      *          whether to settle
156      * @return the delivery
157      */
158     static ProtonDelivery released(ProtonDelivery delivery, bool settle) {
159         delivery.disposition(Released.getInstance(), settle);
160         return delivery;
161     }
162 
163     /**
164      * Modify the given delivery by applying Modified disposition state, with deliveryFailed and underliverableHere flags
165      * as given, and optionally settling.
166      *
167      * @param delivery
168      *          the delivery to update
169      * @param settle
170      *          whether to settle
171      * @param deliveryFailed
172      *          whether the delivery should be treated as failed
173      * @param undeliverableHere
174      *          whether the delivery is considered undeliverable by the related receiver
175      * @return the delivery
176      */
177     static ProtonDelivery modified(ProtonDelivery delivery, bool settle,
178             bool deliveryFailed, bool undeliverableHere) {
179         Modified modified = new Modified();
180         modified.setDeliveryFailed(new Boolean(deliveryFailed));
181         modified.setUndeliverableHere(new Boolean(undeliverableHere));
182 
183         delivery.disposition(modified, settle);
184         return delivery;
185     }
186 
187     static AsyncResult!T future(T)(T value, ErrorCondition err) {
188         if (err.getCondition() !is null) {
189             return failedResult!(T)(new Exception(err.toString()));
190         } else {
191             return succeededResult!(T)(value);
192         }
193     }
194 }