Commit Graph

333 Commits

Author SHA1 Message Date
Clebert Suconic 8a1f267bd5 Revert "ARTEMIS-2423 Improving Consumer/Queue Delivery lock"
This reverts commit 7507a9fd4b.
2019-07-27 10:45:08 -04:00
Clebert Suconic 7507a9fd4b ARTEMIS-2423 Improving Consumer/Queue Delivery lock 2019-07-26 15:05:51 -04:00
Justin Bertram 8484c8a43b ARTEMIS-2389 add details to conn failure logging 2019-07-22 09:56:55 -04:00
Howard Gao c66d62e4b0 ARTEMIS-2390 JMSMessageID header can be null when messages are cross-protocol
If a jms client (be it openwire, amqp, or core jms) receives a message that
is from a different protocol, the JMSMessageID maybe null when the
jms client expects it.
2019-06-27 10:26:34 -04:00
gtully d1add00b00 ARTEMIS-2378 respect openwire removeInfo lastSequenceId when dealing with delivery count 2019-06-17 22:32:33 -04:00
Justin Bertram dbb2b54fa7 [maven-release-plugin] prepare for next development iteration 2019-05-29 22:02:00 -05:00
Justin Bertram 88c686cc99 [maven-release-plugin] prepare release 2.9.0 2019-05-29 21:59:18 -05:00
Clebert Suconic 2ae732cfc8 [maven-release-plugin] prepare for next development iteration 2019-05-16 09:58:27 -04:00
Clebert Suconic 481b9824a8 [maven-release-plugin] prepare release 2.8.1 2019-05-16 09:58:15 -04:00
Clebert Suconic 56152a9e7c [maven-release-plugin] prepare for next development iteration 2019-05-02 16:39:10 -04:00
Clebert Suconic a8e7f9d07a [maven-release-plugin] prepare release 2.8.0 2019-05-02 16:38:58 -04:00
Justin Bertram f584efd574 ARTEMIS-2326 remove pwd params before creating protocol mgr 2019-04-29 20:53:15 -04:00
Clebert Suconic 228f6af4ca [maven-release-plugin] prepare for next development iteration 2019-04-25 16:52:09 -04:00
Clebert Suconic 09d2ba18a7 [maven-release-plugin] prepare release 2.8.0 2019-04-25 16:51:57 -04:00
Clebert Suconic 1e35175a4d ARTEMIS-2311 Dealing with Protocol conversions and JMSReplyTo 2019-04-22 21:45:24 -04:00
Clebert Suconic 516b1a1b9f [maven-release-plugin] prepare for next development iteration 2019-03-14 12:41:04 -04:00
Clebert Suconic c3eb6c12ad [maven-release-plugin] prepare release 2.7.0 2019-03-14 12:40:52 -04:00
Michael André Pearce 7dfa0fe7f4 ARTEMIS-196 Implement Consumer Priority
Add consumer priority support
Includes refactor of consumer iterating in QueueImpl to its own logical class, to be able to implement.
Add OpenWire JMS Test - taken from ActiveMQ5
Add Core JMS Test
Add AMQP Test
Add Docs
2019-01-23 11:19:24 -05:00
Howard Gao b5e7b703b5 ARTEMIS-2230 Exception closing advisory consumers when supportAdvisory=false
When broker's advisory is disabled (supportAdvisory=false) any
advisory consumer won't get created at broker and the advisory
consumer ID won't be stored.

Legacy openwire clients can have a reference of advisory consumer
regardless broker's settings and therefore when it closes the
advisory consumer the broker has no reference to it.
Therefore broker throws an exception like:

javax.jms.IllegalStateException: Cannot
remove a consumer that had not been registered

If the broker stores the consumer info (even it doesn't create
it) the exception can be avoided.
2019-01-22 17:42:57 -05:00
Justin Bertram 61e0354b1a ARTEMIS-1867 FQQN for producers
There's a *slight* semantic change with the behavior of the queue query
and binding query to make them consistent with the address query, namely
that they will return the name of the queue and the name of the address
in every case and the returned names will be not use the FQQN syntax but
will be parsed to reflect their actual names in the broker.
2019-01-18 09:03:30 +00:00
Justin Bertram 6c0f9f8d3d ARTEMIS-2221 avoid unnecessary Bindings instance creation
When trying to get the bindings for an address the getBindingsForAddress
method will create a Bindings instance if there are no bindings for the
address. This is unnecessary in most circumstances so use the
lookupBindingsForAddress method instead and check for null.
2019-01-17 22:49:35 +00:00
Justin Bertram 57aacf784c NO-JIRA fix lgtm.com warnings
Warnings enumerated at
https://lgtm.com/projects/g/apache/activemq-artemis/alerts/?mode=tree&severity=warning
2019-01-17 22:30:28 +00:00
Michael André Pearce 5ac87609e7 ARTEMIS-2142 Refactor of Patchfix ServerJMSMessage
Refactor ServerJMSMessage so it correctly transposes all JMSX headers.
Push common JMSX mappings for JMS to Message Interface mappings into MessageUtil to avoid duplication in ActiveMQMessage and ServerJMSMessage
2018-11-14 09:58:34 -05:00
Francesco Nigro 270b383e80 ARTEMIS-1710 Allow management msgs to exceed global-max-size limit 2018-11-03 23:34:59 +01:00
Clebert Suconic c62146802e ARTEMIS-2159 Fixing OpenWire Blocker Producer
Previous change on Flow control in OpenWire broke Blocked cases
This is a better fix.
2018-11-01 15:43:17 -04:00
Clebert Suconic 02a6d5bb49 ARTEMIS-2159 OpenWire would allow one extra send
Thanks to Otavio Piske collaborating a test change here.
2018-10-31 12:46:12 -04:00
Michael André Pearce faa6ffa3b4 ARTEMIS-2151 JMS Selectors broken in some cases
Create Test Case
Fix OpenWire so selectors are translated
Fix GroupID to call groupId method
2018-10-31 11:55:22 -04:00
Michael André Pearce f30ca44c82 ARTEMIS-2142 Support JMSXGroupSeq -1 to close/reset group.
Add test cases
Add GroupSequence to Message Interface
Implement Support closing/reset group in queue impl
Update Documentation (copy from activemq5)

Change/Fix OpenWireMessageConverter to use default of 0 if not set, for OpenWire as per documentation http://activemq.apache.org/activemq-message-properties.html
2018-10-30 16:24:33 -04:00
Michael André Pearce 547b2aa592 ARTEMIS-2117 Add custom LVQ Key and Non Destructive Queue into Broker
Implement custom LVQ Key and Non-Destructive in broker - protocol agnostic
Make feature configurable via broker.xml, core apis and activemqservercontrol 
Add last-value-key test cases
Add non-destructive with lvq test cases 
Add non-destructive with expiry-delay test cases
Update documents
Add new methods to support create, update with new attributes
Refactor to pass through queue-attributes in client side methods to reduce further method changes for adding new attributes in future and avoid methods with endless parameters. (note: in future this should prob be done server side too)

Update existing test cases and fake impls for new methods/attributes
2018-10-17 20:53:13 -04:00
gtully b812bfdbed ARTEMIS-2103 - use the full openwire consumer queue for the mapped virtual topic queue binding, fix and test 2018-10-10 18:48:11 -04:00
Howard Gao e15f3901e4 ARTEMIS-2013 Can't create durable subscriber to a composite topic
An OpenWire client can use a compound destination name of the form
"a,b,c..." and consume from, or subscribe to, multiple destinations.
Such a compound destination only works for topics when the subscriber
is non-durable. Attempting to create a durable subscription on a
compound address will end up with an error.

The cause is when creating durable subs to multiple topics/addresses
the broker uses the same name to create internal queues, which
causes duplicate name conflict.
2018-08-09 19:38:36 -04:00
Benjamin Graf 4ae8c7bab3 ARTEMIS-1985: Switch from XA_RDONLY to XA_OK as return value for prepare transaction via OpenWire 2018-07-31 12:41:53 -04:00
Clebert Suconic b360fa6063 ARTEMIS-1935: Close of openwire connection should closes all open sessions
This is my ammending to the last commit
I'm adding some extra verifications to the test
and I fixed a leak that already existed on the previous map
2018-06-15 10:33:55 -04:00
Benjamin Graf 39871157b4 ARTEMIS-1935: Close of openwire connection should closes all open sessions 2018-06-15 10:33:55 -04:00
Michael André Pearce a9d9731f0a ARTEMIS-1872 Check for queue exists before creating shared queue
1. Add tests case to verify issue and fix, tests also tests for same behavior using CORE, OPENWIRE and AMQP JMS Clients.
2. Update Core Client to check for queue before creating, sharedQueue as per createQueue logic.
3. Update ServerSessionPacketHandler to handle packets from old clients to perform to implement the same fix server side for older clients.
4. Correct AMQP protocol so correct error code is returned on security exception so that amqp jms can correctly throw JMSsecurityException
5. Correct AMQP protocol to check for queue exists before create
6. Correct OpenWire protocol to check for address exists before create
2018-05-23 13:11:25 -04:00
Francesco Nigro f24d97bfd1 ARTEMIS-1868 Openwire doesn't add delivery count in client ack mode
If a client ack mode consumer receives a message and closes without
acking it, the redelivery of the message won't set the redelivery
flag (JMSRedelivered) because it doesn't increment the delivery count
when message is cancelled back to queue.
(Perf improvement)
2018-05-21 18:02:40 -04:00
Howard Gao 47b31b53d6 ARTEMIS-1868 Openwire doesn't add delivery count in client ack mode
If a client ack mode consumer receives a message and closes without
acking it, the redelivery of the message won't set the redelivery
flag (JMSRedelivered) because it doesn't increment the delivery count
when message is cancelled back to queue.
2018-05-21 18:00:08 -04:00
Clebert Suconic af56b67e38 [maven-release-plugin] prepare for next development iteration 2018-05-16 11:03:26 -04:00
Clebert Suconic bcaa11c2ee [maven-release-plugin] prepare release 2.6.0 2018-05-16 11:03:14 -04:00
Benjamin Graf faec43530d ARTEMIS-1768: Update to fix handling of internalSession for OpenWireConnection 2018-05-05 16:35:39 +02:00
Justin Bertram 3016db699d ARTEMIS-1848 auto-delete auto-created queue for OpenWire 2018-05-03 14:22:20 -05:00
Benjamin Graf 08fd2acb24 ARTEMIS-1768: Fix handling of internalSession for OpenWireConnection 2018-05-03 12:23:57 -04:00
Francesco Nigro 4d27f2e7d7 ARTEMIS-1816 OpenWire should avoid ByteArrayOutputStream lazy allocation
OpenWireMessageConverter::toAMQMessage on bytes messages is lazy
allocating a write buffer with a default size of 1024 even when
it won't be used to write anything.
It avoid an useless allocation by reducing it to new byte[0].
2018-04-20 10:26:33 -04:00
Christopher L. Shannon (cshannon) bddfa4892b ARTEMIS-1803 - Pass ServerConsumer to messageExpired and
messageAcknowledged plugin callback methods

Knowing the consumer that expired or acked a message (if available) is
useful and right now a message reference only contains a consumer id
which by itself is not unique so the actual consumer needs to be passed
2018-04-14 10:34:09 -04:00
Stanislav Knot 5063488b21 ARTEMIS-1798 DEBUG message bad write method arg count - fix 2018-04-10 13:23:30 -04:00
Francesco Nigro f6e8345dbe ARTEMIS-1772 Reduce memory footprint and allocations of QueueImpl
It includes:
- Message References: no longer uses boxed primitives and AtomicInteger
- Node: intrusive nodes no longer need a reference field holding itself
- RefCountMessage: no longer uses AtomicInteger, but AtomicIntegerFieldUpdater
2018-04-03 11:01:38 -04:00
Clebert Suconic e86acd4824 ARTEMIS-1765 Fixing Large Message Compression and Conversion 2018-03-22 16:11:11 -04:00
Clebert Suconic 920af19adb [maven-release-plugin] prepare for next development iteration 2018-03-12 12:46:27 -04:00
Clebert Suconic 5f5b1dcf8f [maven-release-plugin] prepare release 2.5.0 2018-03-12 12:46:16 -04:00
Christopher L. Shannon (cshannon) 29250466ae ARTEMIS-1727 - Make sure transport is stopped on failed OpenWire
connection

To prevent a socket from hanging open by a bad client the broker should
make sure to stop the transport if a connection attempt fails by an
OpenWire client
2018-03-05 07:45:42 -05:00
Christopher L. Shannon (cshannon) da3dd29101 ARTEMIS-1726 - check proper permissions when using OpenWire
Ensure that on queue creation and deletion that the proper permissions
are checked
2018-03-02 16:47:23 -05:00
Christopher L. Shannon (cshannon) 8e9ee80892 ARTEMIS-1711 - Fix openwire exlusive divert
Fixing the failure on send from an OpenWire producer when an exclusive
divert exists
2018-02-28 17:35:56 -05:00
Christopher L. Shannon (cshannon) d4041b5a72 ARTEMIS-1713 - Fix NPE inside OpenWireConnection
fix NPE inside getClientId() in OpenWireConnection
2018-02-28 14:06:36 -05:00
Timothy Bish 8fc1e00d88 ARTEMIS-1712 Add additional null check in TX rollback handler
Check for AMQSession being null before handling various TX state checks
in order to ensure the correct errors are thrown and TX rollback is
handled properly.
2018-02-28 10:46:31 -05:00
Timothy Bish 38fb17703b ARTEMIS-1707 Check for already exists exceptions and ignore
For address and queue create check for the already exists exceptions and
ignore as another client might have just created the same
2018-02-27 16:30:45 -05:00
Francesco Nigro b5fa5ed3b7 ARTEMIS-1656 OpenWire scalability improvements
OpenWireFormat instances are shared between OpenWire connections/sessions/consumers, preventing the clients to scale due to the synchronized marshal/unmarshal on it.

It includes:
- direct transport buffer pooling
- groupId SimpleString pooling
- clientId SimpleString pooling
- reduced ActiveMQDestination[] and AtomicLong allocations on AMQSession:send
- reduced ActiveMQDestination allocations
- refactored shouldBlockProducer path of AMQPSession::send to reduce method size
- exclusive OpenWireFormat per session and connection (in/out) to avoid contention
- refactored trace log to favour inlining
- changed lastSent volatile set into lazy set to avoid full barrier cost on x86
- stateless OpenWireMessageConverter
- send's lock removal thanks to thread-safe NettyConnection
2018-02-27 20:41:24 +08:00
Christopher L. Shannon (cshannon) ea70af15a3 ARTEMIS-1663 - Add new message count and size metrics
Adding new metrics for tracking message counts and sizes on a Queue.
This includes tracking metrics for pending, delivering and scheduled
messages.  The paging store also tracks message size now.
2018-02-08 11:35:12 -05:00
Francesco Nigro 56d68f0b72 ARTEMIS-1607 OpenWire is sending responses too early with durable messages
AMQSession is sending response back without waiting past I/O tasks on StorageManager to be finished
2018-01-23 11:51:41 -05:00
Francesco Nigro 0387b1a842 ARTEMIS-1616 OpenWire improvements
Refactored OpenWireMessageConverter::inbound into a private static method
2018-01-22 18:02:03 -05:00
Francesco Nigro c6b6dd95d1 ARTEMIS-1616 OpenWire improvements
Refactored OpenWireMessageConverter::toAMQMessage into smaller methods
2018-01-22 18:02:03 -05:00
Francesco Nigro e7a1dca7b5 ARTEMIS-1616 OpenWire improvements
Used SimpleString on AMQSession with HDR_DUPLICATE_DETECTION_ID and CONNECTION_ID_PROPERTY_NAME
2018-01-22 18:02:03 -05:00
Francesco Nigro 9650c80ba7 ARTEMIS-1616 OpenWire improvements
Cached Notification Destination check on AMQConsumer to avoid expensive ActiveMQDestination::toString
2018-01-22 18:02:03 -05:00
Francesco Nigro 64724c3520 ARTEMIS-1616 OpenWire improvements
Used SimpleString on OpenWireMessageConverter to avoid translations on CoreMessage
2018-01-22 18:02:03 -05:00
Francesco Nigro 17c0a331ac ARTEMIS-1616 OpenWire improvements
Added existing queues cache to avoid multiple expensive AMQSession::checkAutoCreateQueue calls
2018-01-22 18:02:03 -05:00
Francesco Nigro 54d0161850 ARTEMIS-1616 OpenWire improvements
Refactored OpenWireMessageConverter::inbound into smaller methods
2018-01-22 18:02:03 -05:00
Francesco Nigro 2db4eafc4d ARTEMIS-1616 OpenWire improvements
Avoided copy of CoreMessage when not needed and cached lambda on hot path
2018-01-22 18:02:03 -05:00
gtully 82e4f465ee [ARTEMIS-1030] add support for auto mapping openwire virtual topic consumer destinations to FQQN 2018-01-22 11:10:46 +00:00
gtully ea266cd74b [ARTEMIS-1241] check for FQQN to parse out address and queue for auto creation 2018-01-17 13:23:23 -05:00
Michael André Pearce 98028cdecc ARTEMIS-1586 Refactor to make more generic
* Move byte util code into ByteUtil
* Re-use the new equals method in SimpleString
* Apply same pools/interners to client decode
* Create String to SimpleString pools/interners for property access via String keys (producer and consumer benefits)
* Lazy init the pools on withing the get methods of CoreMessageObjectPools to get the specific pool, to avoid having this scattered every where.
* reduce SimpleString creation in conversion to/from core message methods with JMS wrapper.
* reduce SimpleString creation in conversion to/from Core in OpenWire, AMQP, MQTT.
2018-01-17 09:33:41 +01:00
Howard Gao 6792dcdf27 ARTEMIS-1566 Openwire client can't receive compressed messages
When openwire client uses compressed option to send messages
(jms.useCompression=true) openwire client failed to receive them.
The reason is in OpenwireMessageConverter.toAMQMessage():

1. message.setContent() should be called after setting properties
 (It will cause the compressed content to decompressed before delivering to clients)
2. message.onSend() should not be called here (it should be used
by producers. If used here it changes the internal flags of the
message and cause receive to fail).
2017-12-20 16:00:14 -05:00
Stanislav Knot 45b25d6847 ARTEMIS-1329 fix openwire noLocal flag 2017-12-20 15:59:36 -05:00
Stanislav Knot 04f74425c9 ARTEMIS-1329 testNoLocalReconnect was failing with OpenWire protocol 2017-12-18 22:24:43 -05:00
Howard Gao 1c156e0d47 ARTEMIS-1558 Message Grouping Openwire Interoperability Issue
Openwire message grouping doesn't work because the groupID of
a message is not passed correctly.
2017-12-14 20:30:53 -06:00
Michael André Pearce fa80536615 ARTEMIS-1550 - Support LVQ for OpenWire
Add support for LVQ, using the same property key as core "_AMQ_LVQ_NAME"
Update current LVQ test case to correctly test OpenWire LVQ.
2017-12-09 15:07:21 +00:00
Pat Fox 0b5bddaab5 ARTEMIS-1534 added openwire logging (trace level) to log openwire commands that are received/sent by the broker 2017-12-05 09:39:28 -06:00
saurabhrai 4abca78785 ARTEMIS-1364: Enable internal sorting in hawtio web console 2017-11-29 08:52:33 +00:00
Howard Gao 5fe88e1c66 ARTEMIS-1365 Advisory consumers listed in Console
Openwire clients create consumers to advisory topics to receive
notifications. As a result there are internal queues created
on advisory topics. Those consumer shouldn't be exposed via
management APIs which are used by the Console

To fix that the broker doesn't register any queues from
advisory addresses.

Also refactors a code to remove Openwire specific contants
from AddressInfo class.
2017-11-17 17:39:40 +08:00
Justin Bertram 55d7260a07 ARTEMIS-1510 refactor Maven poms
Clean up unused declared dependencies and undeclared dependencies which
are pulled in transitively.
2017-11-13 17:03:35 -05:00
Justin Bertram 8703d9d51d [maven-release-plugin] prepare for next development iteration 2017-11-01 00:38:57 -05:00
Justin Bertram ec63189a0a [maven-release-plugin] prepare release 2.4.0 2017-11-01 00:38:56 -05:00
Justin Bertram a44b9d5edf [maven-release-plugin] prepare for next development iteration 2017-10-31 12:09:43 -05:00
Justin Bertram 34a7431d1b [maven-release-plugin] prepare release 2.4.0 2017-10-31 12:07:55 -05:00
Justin Bertram 03d56d2cf5 ARTEMIS-1445 fix auto-delete for AMQP and OpenWire 2017-10-05 14:08:52 -05:00
Howard Gao f84d26ebb2 ARTEMIS-1424 Openwire not work with different tightEncoding options
If message senders and receivers uses different
wireformat.tightEncodingEnabled options, broker will get marshalling
problem. This is because when openwire messages are converted to
core messages, and later these core messages converted to openwire
messages, the broker uses a mashaller that comes with the connection
used to carry the messages.

For example, if a producer sents a message using option "wireformat
.tightEncodingEnabled=false" and a receiver tries to receive it
using 'true' for the same option, it'll never get it because the
broker will fail to use a "tight encoding" marshaller to
decode a 'loose encoded' message.

To fix the problem, we always use 'tight encoding' for internal
message converters.
2017-09-19 07:50:24 +08:00
Timothy Bish 342cc83ea4 ARTEMIS-1410 remove redundant code processing openwire destination
Remove some redundant code in the processing of the OpenWire Destination
name, both in the topic handler and in the method in general the
destination name only needs to be converted once and only one
SimpleString instance needs to be created from that which will then feed
all the places that either the String form or the SimpleString form of
the result is needed.
2017-09-13 18:27:39 -04:00
Howard Gao e4fb722ad8 ARTEMIS-1419 OpenWire advisory message never deleted
By default, every openwire connection will create a queue
under the multicast address ActiveMQ.Advisory.TempQueue.
If a openwire client is create temporary queues these queues
will fill up with messages for as long as the associated
openwire connection is alive. It appears these messages
do not get consumed from the queues.

The reason behind is that advisory messages don't require
acknowledgement so the messages stay at the queue.
2017-09-13 18:21:43 -04:00
Clebert Suconic c8982d775b [maven-release-plugin] prepare for next development iteration 2017-09-05 17:03:48 -04:00
Clebert Suconic 84d5ac65b4 [maven-release-plugin] prepare release 2.3.0 2017-09-05 17:03:37 -04:00
Clebert Suconic ed1b268d42 [maven-release-plugin] prepare for next development iteration 2017-08-31 13:48:09 -04:00
Clebert Suconic 21f2a4a52c [maven-release-plugin] prepare release 2.3.0 2017-08-31 13:47:57 -04:00
Martyn Taylor bb3965b7f7 ARTEMIS-1349 Add management views for client objects 2017-08-17 10:44:41 +01:00
gtully ca7197b5c3 [ARTEMIS-1310] add amqp sasl gssapi mechanism support
delegate to the jdk saslServer. Allow acceptor configuration of supported mechanismis; saslMechanisms=<a,b>
and allow login config scope for krb5 to be configured via saslLoginConfigScope=x
2017-08-08 13:28:50 -04:00
Jiri Danek dfb181a8b2 ARTEMIS-1317 Expire messages that got expiredAck() from OpenWire client
This fixes org.apache.activemq.JmsSendReceiveWithMessageExpirationTest
2017-08-03 11:41:58 -04:00
Clebert Suconic fdad83be22 [maven-release-plugin] prepare for next development iteration 2017-07-24 21:21:18 -04:00
Clebert Suconic 71b1cc2a20 [maven-release-plugin] prepare release 2.2.0 2017-07-24 21:21:06 -04:00
Clebert Suconic 8f5f2bbe52 ARTEMIS-1300 Deadlock when Core direct deliverying and AMQP receive 2017-07-20 08:59:32 -04:00
gtully d4150be0d9 ARTEMIS-1264 allow role mapping via chained login modules
Add krb5sslloginmodule that will populate userPrincipal that can be mapped to roles independently
Generalised callback handlers to take a connection and pull certs or peerprincipal based on
callback. This bubbled up into api change in securitystore and security manager
2017-07-06 23:41:02 -04:00
Howard Gao e258bdf188 ARTEMIS-1242 OpenWire Transactions never removed
Openwire doesn't remove the finished transactions
(committed or rolledback).
2017-06-21 11:22:59 -04:00
Michael Andre Pearce 44b7e455cb ARTEMIS-1205: AMQP Shared Durable Subscriber incorrect behaviour
Use AcitveMQDestination for subscription naming, fixing and aligning queue naming in the process.

The change is behind a configuration toggle so to avoid causing any breaking changes for uses not expecting.
2017-06-19 12:44:13 +01:00
Ingo Weiss 45321c65bd [ARTEMIS-1209] JMS OpenWire client cannot read notifications from activemq.notifications topic
Issue: https://issues.apache.org/jira/browse/ARTEMIS-1209
2017-06-07 16:26:33 -04:00