26
26
27
27
import com .ericsson .eiffel .remrem .publish .config .PropertiesConfig ;
28
28
import com .ericsson .eiffel .remrem .publish .exception .RemRemPublishException ;
29
+ import com .ericsson .eiffel .remrem .publish .exception .NackException ;
29
30
import com .rabbitmq .client .AMQP .BasicProperties ;
30
31
import com .rabbitmq .client .Channel ;
31
32
import com .rabbitmq .client .Connection ;
@@ -51,6 +52,9 @@ public class RabbitMqProperties {
51
52
private String domainId ;
52
53
private Integer channelsCount ;
53
54
private boolean createExchangeIfNotExisting ;
55
+ private Long waitForConfirmsTimeOut ;
56
+ public static final Long DEFAULT_WAIT_FOR_CONFIRMS_TIMEOUT = 5000L ;
57
+ public static final Integer DEFAULT_CHANNEL_COUNT = 1 ;
54
58
55
59
private Connection rabbitConnection ;
56
60
private String protocol ;
@@ -59,6 +63,15 @@ public class RabbitMqProperties {
59
63
60
64
Logger log = (Logger ) LoggerFactory .getLogger (RMQHelper .class );
61
65
66
+
67
+ public Long getWaitForConfirmsTimeOut () {
68
+ return waitForConfirmsTimeOut ;
69
+ }
70
+
71
+ public void setWaitForConfirmsTimeOut (Long waitForConfirmsTimeOut ) {
72
+ this .waitForConfirmsTimeOut = waitForConfirmsTimeOut ;
73
+ }
74
+
62
75
public String getHost () {
63
76
return host ;
64
77
}
@@ -219,20 +232,24 @@ public void init() throws RemRemPublishException {
219
232
220
233
/**
221
234
* This method is used to create Rabbitmq connection and channels
235
+ * @throws RemRemPublishException
222
236
*/
223
- public void createRabbitMqConnection () {
237
+ public void createRabbitMqConnection () throws RemRemPublishException {
224
238
try {
225
239
rabbitConnection = factory .newConnection ();
226
240
log .info ("Connected to RabbitMQ." );
227
241
rabbitChannels = new ArrayList <>();
228
242
if (channelsCount == null || channelsCount == 0 ) {
229
- channelsCount = 1 ;
243
+ channelsCount = DEFAULT_CHANNEL_COUNT ;
230
244
}
231
245
for (int i = 0 ; i < channelsCount ; i ++) {
232
- rabbitChannels .add (rabbitConnection .createChannel ());
246
+ Channel channel = rabbitConnection .createChannel ();
247
+ channel .confirmSelect ();
248
+ rabbitChannels .add (channel );
233
249
}
234
250
} catch (IOException | TimeoutException e ) {
235
251
log .error (e .getMessage (), e );
252
+ throw new RemRemPublishException ("Failed to create connection for Rabbitmq ::" + factory .getHost () + ":" + factory .getPort ());
236
253
}
237
254
}
238
255
@@ -276,6 +293,9 @@ private void initService() {
276
293
if (channelsCount == null ) {
277
294
channelsCount = Integer .getInteger (getValuesFromSystemProperties (protocol + ".rabbitmq.channelsCount" ));
278
295
}
296
+ if (waitForConfirmsTimeOut == null ) {
297
+ waitForConfirmsTimeOut = Long .getLong (getValuesFromSystemProperties (protocol + ".rabbitmq.waitForConfirmsTimeOut" ));
298
+ }
279
299
}
280
300
281
301
@@ -285,6 +305,7 @@ private void setValues() {
285
305
virtualHost = getValuesFromSystemProperties (PropertiesConfig .VIRTUAL_HOST );
286
306
domainId = getValuesFromSystemProperties (PropertiesConfig .DOMAIN_ID );
287
307
channelsCount = Integer .getInteger (PropertiesConfig .CHANNELS_COUNT );
308
+ waitForConfirmsTimeOut = Long .getLong (PropertiesConfig .WAIT_FOR_CONFIRMS_TIME_OUT );
288
309
tlsVer = getValuesFromSystemProperties (PropertiesConfig .TLS );
289
310
exchangeName = getValuesFromSystemProperties (PropertiesConfig .EXCHANGE_NAME );
290
311
usePersitance = Boolean .getBoolean (PropertiesConfig .USE_PERSISTENCE );
@@ -400,40 +421,60 @@ private boolean hasExchange() throws RemRemPublishException {
400
421
* @param routingKey
401
422
* @param msg is Eiffel Event
402
423
* @throws IOException
424
+ * @throws NackException
425
+ * @throws TimeoutException
426
+ * @throws RemRemPublishException
403
427
*/
404
- public void send (String routingKey , String msg ) throws IOException {
405
-
406
- Channel channel = giveMeRandomChannel ();
407
- channel .addShutdownListener (new ShutdownListener () {
408
- public void shutdownCompleted (ShutdownSignalException cause ) {
409
- // Beware that proper synchronization is needed here
410
- if (cause .isInitiatedByApplication ()) {
411
- log .debug ("Shutdown is initiated by application. Ignoring it." );
412
- } else {
413
- log .error ("Shutdown is NOT initiated by application." );
414
- log .error (cause .getMessage ());
415
- boolean cliMode = Boolean .getBoolean (PropertiesConfig .CLI_MODE );
416
- if (cliMode ) {
417
- System .exit (-3 );
428
+ public void send (String routingKey , String msg )
429
+ throws IOException , NackException , TimeoutException , RemRemPublishException {
430
+ Channel channel = giveMeRandomChannel ();
431
+ channel .addShutdownListener (new ShutdownListener () {
432
+ public void shutdownCompleted (ShutdownSignalException cause ) {
433
+ // Beware that proper synchronization is needed here
434
+ if (cause .isInitiatedByApplication ()) {
435
+ log .debug ("Shutdown is initiated by application. Ignoring it." );
436
+ } else {
437
+ log .error ("Shutdown is NOT initiated by application." );
438
+ log .error (cause .getMessage ());
439
+ boolean cliMode = Boolean .getBoolean (PropertiesConfig .CLI_MODE );
440
+ if (cliMode ) {
441
+ System .exit (-3 );
442
+ }
418
443
}
419
444
}
445
+ });
446
+ BasicProperties msgProps = MessageProperties .BASIC ;
447
+ if (usePersitance )
448
+ msgProps = MessageProperties .PERSISTENT_BASIC ;
449
+ try {
450
+ channel .basicPublish (exchangeName , routingKey , msgProps , msg .getBytes ());
451
+ log .info ("Published message with size {} bytes on exchange '{}' with routing key '{}'" ,
452
+ msg .getBytes ().length , exchangeName , routingKey );
453
+ if (waitForConfirmsTimeOut == null || waitForConfirmsTimeOut == 0 ) {
454
+ waitForConfirmsTimeOut = DEFAULT_WAIT_FOR_CONFIRMS_TIMEOUT ;
420
455
}
421
- });
422
-
423
- BasicProperties msgProps = MessageProperties .BASIC ;
424
- if (usePersitance )
425
- msgProps = MessageProperties .PERSISTENT_BASIC ;
426
-
427
- channel .basicPublish (exchangeName , routingKey , msgProps , msg .getBytes ());
428
- log .info ("Published message with size {} bytes on exchange '{}' with routing key '{}'" , msg .getBytes ().length ,
429
- exchangeName , routingKey );
456
+ channel .waitForConfirmsOrDie (waitForConfirmsTimeOut );
457
+ } catch (InterruptedException | IOException e ) {
458
+ log .error ("Failed to publish message due to " + e .getMessage ());
459
+ throw new NackException ("The message is nacked due to " + e .getMessage (), e );
460
+ } catch (TimeoutException e ) {
461
+ log .error ("Failed to publish message due to " + e .getMessage ());
462
+ throw new TimeoutException ("Timeout waiting for ACK " + e .getMessage ());
463
+ } catch (Exception e ) {
464
+ log .error (e .getMessage (), e );
465
+ if (!channel .isOpen ()&& rabbitConnection .isOpen ()){
466
+ throw new RemRemPublishException ("Channel was closed for Rabbitmq connection ::" + factory .getHost () + factory .getPort ());
467
+ }
468
+ throw new IOException ("Failed to publish message due to " + e .getMessage ());
469
+ }
430
470
}
431
471
432
472
/**
433
473
* This method is used to give random channel
434
474
* @return channel
475
+ * @throws RemRemPublishException
435
476
*/
436
- private Channel giveMeRandomChannel () {
477
+ private Channel giveMeRandomChannel () throws RemRemPublishException {
437
478
if ((rabbitConnection == null || !rabbitConnection .isOpen ())) {
438
479
createRabbitMqConnection ();
439
480
}
0 commit comments