Class PostgresqlDurableQueues
java.lang.Object
dk.cloudcreate.essentials.components.queue.postgresql.PostgresqlDurableQueues
- All Implemented Interfaces:
dk.cloudcreate.essentials.components.foundation.Lifecycle,dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues,dk.cloudcreate.essentials.shared.Lifecycle
public final class PostgresqlDurableQueues
extends Object
implements dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
Postgresql version of the
Works together with
Security
Note:
To support customization of storage table name, the
Security Note:
It is the responsibility of the user of this component to sanitize the
The
The
However, Essentials components as well as
The responsibility for implementing protective measures against SQL Injection lies exclusively with the users/developers using the Essentials components and its supporting classes.
Users must ensure thorough sanitization and validation of API input parameters, column, table, and index names.
Insufficient attention to these practices may leave the application vulnerable to SQL injection, potentially endangering the security and integrity of the database.
The responsibility for implementing protective measures against SQL Injection lies exclusively with the users/developers using the Essentials components and its supporting classes.
Users must ensure thorough sanitization and validation of API input parameters, column, table, and index names.
Insufficient attention to these practices may leave the application vulnerable to SQL injection, potentially endangering the security and integrity of the database.
It is highly recommended that the
To mitigate the risk of SQL injection attacks, external or untrusted inputs should never directly provide the
DurableQueues concept.Works together with
UnitOfWorkFactory in order to support queuing message together with business logic (such as failing to handle an Event, etc.)Security
DurableQueues allows the user of the component to override the getSharedQueueTableName(), which is the name of the table that will contain all messages (across all QueueName's)Note:
To support customization of storage table name, the
sharedQueueTableName will be directly used in constructing SQL statements
through string concatenation, which exposes the component to SQL injection attacks.Security Note:
It is the responsibility of the user of this component to sanitize the
sharedQueueTableName
to ensure the security of all the SQL statements generated by this component.The
PostgresqlDurableQueues component will
call the PostgresqlUtil.checkIsValidTableOrColumnName(String) method to validate the table name as a first line of defense.The
PostgresqlUtil.checkIsValidTableOrColumnName(String) provides an initial layer of defense against SQL injection by applying naming conventions intended to reduce the risk of malicious input.However, Essentials components as well as
PostgresqlUtil.checkIsValidTableOrColumnName(String) does not offer exhaustive protection, nor does it assure the complete security of the resulting SQL against SQL injection threats.The responsibility for implementing protective measures against SQL Injection lies exclusively with the users/developers using the Essentials components and its supporting classes.
Users must ensure thorough sanitization and validation of API input parameters, column, table, and index names.
Insufficient attention to these practices may leave the application vulnerable to SQL injection, potentially endangering the security and integrity of the database.
The responsibility for implementing protective measures against SQL Injection lies exclusively with the users/developers using the Essentials components and its supporting classes.
Users must ensure thorough sanitization and validation of API input parameters, column, table, and index names.
Insufficient attention to these practices may leave the application vulnerable to SQL injection, potentially endangering the security and integrity of the database.
It is highly recommended that the
sharedQueueTableName value is only derived from a controlled and trusted source.To mitigate the risk of SQL injection attacks, external or untrusted inputs should never directly provide the
sharedQueueTableName value.-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprotected static enumstatic classNested classes/interfaces inherited from interface dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues.QueueingSortOrder -
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final Stringprotected ConcurrentMap<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName,Instant> Contains the timestamp of the last performedresetMessagesStuckBeingDelivered(QueueName)check
Only used iftransactionalModehas valueTransactionalMode.SingleOperationTransaction -
Constructor Summary
ConstructorsConstructorDescriptionPostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory) CreateDurableQueueswith sharedQueueTableName: "durable_queues" and the defaultJacksonJSONSerializerusingcreateDefaultObjectMapper()configurationPostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer) CreateDurableQueueswith custom jsonSerializer with sharedQueueTableName: "durable_queues"PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer, String sharedQueueTableName, dk.cloudcreate.essentials.components.foundation.postgresql.MultiTableChangeListener<dk.cloudcreate.essentials.components.foundation.postgresql.TableChangeNotification> multiTableChangeListener, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory) CreateDurableQueueswith custom jsonSerializer and sharedQueueTableNamePostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer, String sharedQueueTableName, dk.cloudcreate.essentials.components.foundation.postgresql.MultiTableChangeListener<dk.cloudcreate.essentials.components.foundation.postgresql.TableChangeNotification> multiTableChangeListener, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory, dk.cloudcreate.essentials.components.foundation.messaging.queue.TransactionalMode transactionalMode, Duration messageHandlingTimeout) CreateDurableQueueswith custom jsonSerializer and sharedQueueTableNamePostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory) CreateDurableQueueswith custom jsonSerializer with sharedQueueTableName: "durable_queues"PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory) CreateDurableQueueswith sharedQueueTableName: "durable_queues" and the defaultJacksonJSONSerializerusingcreateDefaultObjectMapper()configuration -
Method Summary
Modifier and TypeMethodDescriptionfinal booleanacknowledgeMessageAsHandled(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.AcknowledgeMessageAsHandled operation) final dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesaddInterceptor(dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesInterceptor interceptor) builder()final dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueueConsumerconsumeFromQueue(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue operation) static com.fasterxml.jackson.databind.ObjectMapperDefaultObjectMappersupportingJdk8Module,JavaTimeModule,EssentialTypesJacksonModuleandEssentialsImmutableJacksonModule, which is used together with theJacksonJSONSerializerprotected dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizercreateQueuePollingOptimizerFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue operation) Override this method to provide anotherQueuePollingOptimizerthan the defaultQueuePollingOptimizer.SimpleQueuePollingOptimizer
Only called if thePostgresqlDurableQueuesis configured with aMultiTableChangeListenerfinal booleandeleteMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.DeleteMessage operation) final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>getDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetDeadLetterMessage operation) final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>getDeadLetterMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetDeadLetterMessages operation) final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesInterceptor>final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>getNextMessageReadyForDelivery(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetNextMessageReadyForDelivery operation) final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>getQueuedMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetQueuedMessage operation) dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessageCountsgetQueuedMessageCountsFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetQueuedMessageCountsFor operation) final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>getQueuedMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetQueuedMessages operation) final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName>getQueueNameFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId queueEntryId) final Set<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName>final StringThe name of the shared table where all queue messages are storedfinal longgetTotalDeadLetterMessagesQueuedFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetTotalDeadLetterMessagesQueuedFor operation) final longgetTotalMessagesQueuedFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetTotalMessagesQueuedFor operation) final dk.cloudcreate.essentials.components.foundation.messaging.queue.TransactionalModefinal Optional<dk.cloudcreate.essentials.components.foundation.transaction.UnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.UnitOfWork>>final booleanhasMessagesQueuedFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName) final booleanfinal Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>markAsDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.MarkAsDeadLetterMessage operation) final intpurgeQueue(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.PurgeQueue operation) final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.NextQueuedMessage>queryForMessagesSoonReadyForDelivery(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName, Instant withNextDeliveryTimestampAfter, int maxNumberOfMessagesToReturn) protected final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>queryQueuedMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName, dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues.QueueingSortOrder queueingSortOrder, PostgresqlDurableQueues.IncludeMessages includeMessages, long startIndex, long pageSize) final dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryIdqueueMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.QueueMessage operation) protected final dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryIdqueueMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName, dk.cloudcreate.essentials.components.foundation.messaging.queue.Message message, boolean isDeadLetterMessage, Optional<Exception> causeOfEnqueuing, Optional<Duration> deliveryDelay) final dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryIdqueueMessageAsDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.QueueMessageAsDeadLetterMessage operation) final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId>queueMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.QueueMessages operation) final dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesremoveInterceptor(dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesInterceptor interceptor) protected final voidresetMessagesStuckBeingDelivered(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName) This operation will scan for messages that has been marked asQueuedMessage.isBeingDelivered()for longer thanmessageHandlingTimeoutMs
All messages found will haveQueuedMessage.isBeingDelivered()andQueuedMessage.getDeliveryTimestamp()reset
Only relevant for when usingTransactionalMode.SingleOperationTransactionfinal Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>resurrectDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ResurrectDeadLetterMessage operation) final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage>retryMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.RetryMessage operation) final voidstart()final voidstop()Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
acknowledgeMessageAsHandled, addInterceptors, consumeFromQueue, consumeFromQueue, deleteMessage, getDeadLetterMessage, getDeadLetterMessages, getNextMessageReadyForDelivery, getQueuedMessage, getQueuedMessageCountsFor, getQueuedMessages, getTotalDeadLetterMessagesQueuedFor, getTotalMessagesQueuedFor, markAsDeadLetterMessage, markAsDeadLetterMessage, markAsDeadLetterMessage, purgeQueue, queryForMessagesSoonReadyForDelivery, queueMessage, queueMessage, queueMessage, queueMessage, queueMessage, queueMessageAsDeadLetterMessage, queueMessages, queueMessages, queueMessages, resurrectDeadLetterMessage, retryMessage
-
Field Details
-
DEFAULT_DURABLE_QUEUES_TABLE_NAME
- See Also:
-
lastResetStuckMessagesCheckTimestamps
protected ConcurrentMap<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName,Instant> lastResetStuckMessagesCheckTimestampsContains the timestamp of the last performedresetMessagesStuckBeingDelivered(QueueName)check
Only used iftransactionalModehas valueTransactionalMode.SingleOperationTransaction
-
-
Constructor Details
-
PostgresqlDurableQueues
public PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory) CreateDurableQueueswith sharedQueueTableName: "durable_queues" and the defaultJacksonJSONSerializerusingcreateDefaultObjectMapper()configuration- Parameters:
unitOfWorkFactory- theUnitOfWorkFactoryneeded to access the database
-
PostgresqlDurableQueues
public PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory) CreateDurableQueueswith sharedQueueTableName: "durable_queues" and the defaultJacksonJSONSerializerusingcreateDefaultObjectMapper()configuration- Parameters:
unitOfWorkFactory- theUnitOfWorkFactoryneeded to access the databasequeuePollingOptimizerFactory- optionalQueuePollingOptimizerfactory that creates aQueuePollingOptimizerperConsumeFromQueuecommand - if set to nullcreateQueuePollingOptimizerFor(ConsumeFromQueue)is used instead
-
PostgresqlDurableQueues
public PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer) CreateDurableQueueswith custom jsonSerializer with sharedQueueTableName: "durable_queues"- Parameters:
unitOfWorkFactory- theUnitOfWorkFactoryneeded to access the databasejsonSerializer- theJSONSerializerthat is used to serialize/deserialize message payloads
-
PostgresqlDurableQueues
public PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory) CreateDurableQueueswith custom jsonSerializer with sharedQueueTableName: "durable_queues"- Parameters:
unitOfWorkFactory- theUnitOfWorkFactoryneeded to access the databasejsonSerializer- theJSONSerializerthat is used to serialize/deserialize message payloadsqueuePollingOptimizerFactory- optionalQueuePollingOptimizerfactory that creates aQueuePollingOptimizerperConsumeFromQueuecommand - if set to nullcreateQueuePollingOptimizerFor(ConsumeFromQueue)is used instead
-
PostgresqlDurableQueues
public PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer, String sharedQueueTableName, dk.cloudcreate.essentials.components.foundation.postgresql.MultiTableChangeListener<dk.cloudcreate.essentials.components.foundation.postgresql.TableChangeNotification> multiTableChangeListener, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory) CreateDurableQueueswith custom jsonSerializer and sharedQueueTableName- Parameters:
unitOfWorkFactory- theUnitOfWorkFactoryneeded to access the databasejsonSerializer- theJSONSerializerthat is used to serialize/deserialize message payloadssharedQueueTableName- the name of the table that will contain all messages (across allQueueName's)
Note:
To support customization of storage table name, thesharedQueueTableNamewill be directly used in constructing SQL statements through string concatenation, which exposes the component to SQL injection attacks.
Security Note:
It is the responsibility of the user of this component to sanitize thesharedQueueTableNameto ensure the security of all the SQL statements generated by this component.
ThePostgresqlDurableQueuescomponent will call thePostgresqlUtil.checkIsValidTableOrColumnName(String)method to validate the table name as a first line of defense.
ThePostgresqlUtil.checkIsValidTableOrColumnName(String)provides an initial layer of defense against SQL injection by applying naming conventions intended to reduce the risk of malicious input.
However, Essentials components as well asPostgresqlUtil.checkIsValidTableOrColumnName(String)does not offer exhaustive protection, nor does it assure the complete security of the resulting SQL against SQL injection threats.
The responsibility for implementing protective measures against SQL Injection lies exclusively with the users/developers using the Essentials components and its supporting classes.
Users must ensure thorough sanitization and validation of API input parameters, column, table, and index names.
Insufficient attention to these practices may leave the application vulnerable to SQL injection, potentially endangering the security and integrity of the database.
It is highly recommended that thesharedQueueTableNamevalue is only derived from a controlled and trusted source.
To mitigate the risk of SQL injection attacks, external or untrusted inputs should never directly provide thesharedQueueTableNamevalue.multiTableChangeListener- optionalMultiTableChangeListenerthat allowsPostgresqlDurableQueuesto useQueuePollingOptimizerqueuePollingOptimizerFactory- optionalQueuePollingOptimizerfactory that creates aQueuePollingOptimizerperConsumeFromQueuecommand - if set to nullcreateQueuePollingOptimizerFor(ConsumeFromQueue)is used instead
-
PostgresqlDurableQueues
public PostgresqlDurableQueues(dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.jdbi.HandleAwareUnitOfWork> unitOfWorkFactory, dk.cloudcreate.essentials.components.foundation.json.JSONSerializer jsonSerializer, String sharedQueueTableName, dk.cloudcreate.essentials.components.foundation.postgresql.MultiTableChangeListener<dk.cloudcreate.essentials.components.foundation.postgresql.TableChangeNotification> multiTableChangeListener, Function<dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue, dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer> queuePollingOptimizerFactory, dk.cloudcreate.essentials.components.foundation.messaging.queue.TransactionalMode transactionalMode, Duration messageHandlingTimeout) CreateDurableQueueswith custom jsonSerializer and sharedQueueTableName- Parameters:
unitOfWorkFactory- theUnitOfWorkFactoryneeded to access the databasejsonSerializer- theJSONSerializerthat is used to serialize/deserialize message payloadssharedQueueTableName- the name of the table that will contain all messages (across allQueueName's)
Note:
To support customization of storage table name, thesharedQueueTableNamewill be directly used in constructing SQL statements through string concatenation, which exposes the component to SQL injection attacks.
Security Note:
It is the responsibility of the user of this component to sanitize thesharedQueueTableNameto ensure the security of all the SQL statements generated by this component.
ThePostgresqlDurableQueuescomponent will call thePostgresqlUtil.checkIsValidTableOrColumnName(String)method to validate the table name as a first line of defense.
ThePostgresqlUtil.checkIsValidTableOrColumnName(String)provides an initial layer of defense against SQL injection by applying naming conventions intended to reduce the risk of malicious input.
However, Essentials components as well asPostgresqlUtil.checkIsValidTableOrColumnName(String)does not offer exhaustive protection, nor does it assure the complete security of the resulting SQL against SQL injection threats.
The responsibility for implementing protective measures against SQL Injection lies exclusively with the users/developers using the Essentials components and its supporting classes.
Users must ensure thorough sanitization and validation of API input parameters, column, table, and index names.
Insufficient attention to these practices may leave the application vulnerable to SQL injection, potentially endangering the security and integrity of the database.
It is highly recommended that thesharedQueueTableNamevalue is only derived from a controlled and trusted source.
To mitigate the risk of SQL injection attacks, external or untrusted inputs should never directly provide thesharedQueueTableNamevalue.multiTableChangeListener- optionalMultiTableChangeListenerthat allowsPostgresqlDurableQueuesto useQueuePollingOptimizerqueuePollingOptimizerFactory- optionalQueuePollingOptimizerfactory that creates aQueuePollingOptimizerperConsumeFromQueuecommand - if set to nullcreateQueuePollingOptimizerFor(ConsumeFromQueue)is used insteadtransactionalMode- TheTransactionalModefor thisDurableQueuesinstance. If set toTransactionalMode.SingleOperationTransactionthen the consumer MUST call theDurableQueues.acknowledgeMessageAsHandled(AcknowledgeMessageAsHandled)explicitly in a newUnitOfWorkmessageHandlingTimeout- Only required iftransactionalModeisTransactionalMode.SingleOperationTransaction.
The parameter defines the timeout for messages being delivered, but haven't yet been acknowledged. After this timeout the message delivery will be reset and the message will again be a candidate for delivery
-
-
Method Details
-
builder
-
getInterceptors
public final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesInterceptor> getInterceptors() -
start
public final void start()- Specified by:
startin interfacedk.cloudcreate.essentials.shared.Lifecycle
-
stop
public final void stop()- Specified by:
stopin interfacedk.cloudcreate.essentials.shared.Lifecycle
-
isStarted
public final boolean isStarted()- Specified by:
isStartedin interfacedk.cloudcreate.essentials.shared.Lifecycle
-
getTransactionalMode
public final dk.cloudcreate.essentials.components.foundation.messaging.queue.TransactionalMode getTransactionalMode()- Specified by:
getTransactionalModein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getUnitOfWorkFactory
public final Optional<dk.cloudcreate.essentials.components.foundation.transaction.UnitOfWorkFactory<? extends dk.cloudcreate.essentials.components.foundation.transaction.UnitOfWork>> getUnitOfWorkFactory()- Specified by:
getUnitOfWorkFactoryin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getQueueNames
public final Set<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName> getQueueNames()- Specified by:
getQueueNamesin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
consumeFromQueue
public final dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueueConsumer consumeFromQueue(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue operation) - Specified by:
consumeFromQueuein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
createQueuePollingOptimizerFor
protected dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuePollingOptimizer createQueuePollingOptimizerFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ConsumeFromQueue operation) Override this method to provide anotherQueuePollingOptimizerthan the defaultQueuePollingOptimizer.SimpleQueuePollingOptimizer
Only called if thePostgresqlDurableQueuesis configured with aMultiTableChangeListener- Parameters:
operation- the operation for which theQueuePollingOptimizerwill be responsible- Returns:
- the
QueuePollingOptimizer
-
queueMessage
public final dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId queueMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.QueueMessage operation) - Specified by:
queueMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
queueMessageAsDeadLetterMessage
public final dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId queueMessageAsDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.QueueMessageAsDeadLetterMessage operation) - Specified by:
queueMessageAsDeadLetterMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
queueMessage
protected final dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId queueMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName, dk.cloudcreate.essentials.components.foundation.messaging.queue.Message message, boolean isDeadLetterMessage, Optional<Exception> causeOfEnqueuing, Optional<Duration> deliveryDelay) -
queueMessages
public final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId> queueMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.QueueMessages operation) - Specified by:
queueMessagesin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
retryMessage
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> retryMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.RetryMessage operation) - Specified by:
retryMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
markAsDeadLetterMessage
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> markAsDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.MarkAsDeadLetterMessage operation) - Specified by:
markAsDeadLetterMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
resurrectDeadLetterMessage
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> resurrectDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.ResurrectDeadLetterMessage operation) - Specified by:
resurrectDeadLetterMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
acknowledgeMessageAsHandled
public final boolean acknowledgeMessageAsHandled(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.AcknowledgeMessageAsHandled operation) - Specified by:
acknowledgeMessageAsHandledin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
deleteMessage
public final boolean deleteMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.DeleteMessage operation) - Specified by:
deleteMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getNextMessageReadyForDelivery
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> getNextMessageReadyForDelivery(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetNextMessageReadyForDelivery operation) - Specified by:
getNextMessageReadyForDeliveryin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
resetMessagesStuckBeingDelivered
protected final void resetMessagesStuckBeingDelivered(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName) This operation will scan for messages that has been marked asQueuedMessage.isBeingDelivered()for longer thanmessageHandlingTimeoutMs
All messages found will haveQueuedMessage.isBeingDelivered()andQueuedMessage.getDeliveryTimestamp()reset
Only relevant for when usingTransactionalMode.SingleOperationTransaction- Parameters:
queueName- the queue for which we're looking for messages stuck being marked asQueuedMessage.isBeingDelivered()
-
hasMessagesQueuedFor
public final boolean hasMessagesQueuedFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName) - Specified by:
hasMessagesQueuedForin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getTotalMessagesQueuedFor
public final long getTotalMessagesQueuedFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetTotalMessagesQueuedFor operation) - Specified by:
getTotalMessagesQueuedForin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getQueuedMessageCountsFor
public dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessageCounts getQueuedMessageCountsFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetQueuedMessageCountsFor operation) - Specified by:
getQueuedMessageCountsForin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getTotalDeadLetterMessagesQueuedFor
public final long getTotalDeadLetterMessagesQueuedFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetTotalDeadLetterMessagesQueuedFor operation) - Specified by:
getTotalDeadLetterMessagesQueuedForin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
purgeQueue
public final int purgeQueue(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.PurgeQueue operation) - Specified by:
purgeQueuein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
queryForMessagesSoonReadyForDelivery
public final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.NextQueuedMessage> queryForMessagesSoonReadyForDelivery(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName, Instant withNextDeliveryTimestampAfter, int maxNumberOfMessagesToReturn) - Specified by:
queryForMessagesSoonReadyForDeliveryin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getQueuedMessages
public final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> getQueuedMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetQueuedMessages operation) - Specified by:
getQueuedMessagesin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getDeadLetterMessages
public final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> getDeadLetterMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetDeadLetterMessages operation) - Specified by:
getDeadLetterMessagesin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
queryQueuedMessages
protected final List<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> queryQueuedMessages(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName queueName, dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues.QueueingSortOrder queueingSortOrder, PostgresqlDurableQueues.IncludeMessages includeMessages, long startIndex, long pageSize) -
addInterceptor
public final dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues addInterceptor(dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesInterceptor interceptor) - Specified by:
addInterceptorin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
removeInterceptor
public final dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues removeInterceptor(dk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueuesInterceptor interceptor) - Specified by:
removeInterceptorin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getQueueNameFor
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueName> getQueueNameFor(dk.cloudcreate.essentials.components.foundation.messaging.queue.QueueEntryId queueEntryId) - Specified by:
getQueueNameForin interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getDeadLetterMessage
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> getDeadLetterMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetDeadLetterMessage operation) - Specified by:
getDeadLetterMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
getQueuedMessage
public final Optional<dk.cloudcreate.essentials.components.foundation.messaging.queue.QueuedMessage> getQueuedMessage(dk.cloudcreate.essentials.components.foundation.messaging.queue.operations.GetQueuedMessage operation) - Specified by:
getQueuedMessagein interfacedk.cloudcreate.essentials.components.foundation.messaging.queue.DurableQueues
-
createDefaultObjectMapper
public static com.fasterxml.jackson.databind.ObjectMapper createDefaultObjectMapper()DefaultObjectMappersupportingJdk8Module,JavaTimeModule,EssentialTypesJacksonModuleandEssentialsImmutableJacksonModule, which is used together with theJacksonJSONSerializer- Returns:
- the default
ObjectMapper
-