[[Message_Driven_Beans_Controlled_Delivery]] = Message Driven Beans Controlled Delivery There are three mechanisms in Wildfly that allow controlling if a specific MDB is actively receiving or not messages: * delivery active * delivery groups * clustered singleton We will see each one of them in the following sections. [[delivery-active]] == Delivery Active Delivery active is simply an attribute associated with the MDB that indicates if the MDB is receiving messages or not. If an MDB is not currently receiving messages, the messages will be saved in the queue or topic for later, according to the rules of the topic/queue. You can configure delivery active using xml or annotations, and you can change its value after deployment using the cli. * jboss-ejb3.xml: In the jboss-ejb3 xml file, configure the value of active as false to mark that the MDB will not be receiving messages as soon as it is deployed: [source, xml] ----             HelloWorldQueueMDB false     ---- You can use a wildcard "*" in the place of ejb-name if you want to apply that active value to all MDBs in your application. * annotation Alternatively, you can use the org.jboss.ejb3.annotation.DeliveryActive annotation, as in the example below: [source, java] ---- @MessageDriven(name = "HelloWorldMDB", activationConfig = {   @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),   @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/HELLOWORLDMDBQueue"),   @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })   @DeliveryActive(false)   public class HelloWorldMDB implements MessageListener { public void onMessage(Message rcvMessage) { // ... } } ---- [[start-delivery-and-stop-delivery]] === Start-delivery and Stop-Delivery These management operations dynamically change the value of the active attribute, enabling or disabling delivery for the MDB. at runtime To use them, connect to the Wildfly instance you want to manage, then enter the path of the MDB you want to manage delivery for: [source,ruby] ---- [standalone@localhost:9990 /] cd deployment=jboss-helloworld-mdb.war/subsystem=ejb3/message-driven-bean=HelloWorldMDB   [standalone@localhost:9990 message-driven-bean=HelloWorldMDB] :stop-delivery {"outcome" => "success"}   [standalone@localhost:9990 message-driven-bean=HelloWorldMDB] :start-delivery {"outcome" => "success"} ---- [[delivery-groups]] == Delivery Groups Delivery groups provide a straightforward way to manage delivery for a group of MDBs. Every MDB belonging to a delivery group has delivery active if and only if that group is active, and has delivery inactive whenever the group is not active. You can add a delivery group to the ejb3 subsystem using either the subsystem xml or cli. Next, we will see examples of each case. In those examples we will add only a single delivery group, but keep in mind that you can add as many delivery groups as you need to a Wildfly instance. * the ejb3 subsystem xml (located in your configuration xml, such as standalone.xml) [source,xml] ---- ...   ... ... ---- The example above adds a delivery group named "mdb-group-name" (you can use whatever name suits you best as the group name). The "true" active attribute indicates that all MDBs belonging to that group will have delivery active right after deployment. If you mark that attribute as false, you are indicating that every MDB belonging to the group will not start receiving messages after deployment, a condition that will remain until the group becomes active. * jboss-cli You can add a mdb-delivery-group using the add command as below: [source,ruby] ---- [standalone@localhost:9990 /] ./subsystem=ejb3/mdb-delivery-group=mdb-group-name:add {"outcome" => "success"} ---- [[reading-and-writing-the-delivery-state-of-a-delivery-group]] === Reading and Writing the Delivery State of a Delivery Group You can check whether delivery is active for a group by reading the active attribute, which defaults to true: [source,ruby] ---- [standalone@localhost:9990 /] ./subsystem=ejb3/mdb-delivery-group=mdb-group-name:read-attribute(name=active) { "outcome" => "success", "result" => true } ---- To make the the delivery-group inactive, just write the active attribute with a false value: [source,ruby] ---- [standalone@localhost:9990 /] ./subsystem=ejb3/mdb-delivery-group=mdb-group-name:write-attribute(name=active,value=false) {"outcome" => "success"}   [standalone@localhost:9990 /] ./subsystem=ejb3/mdb-delivery-group=mdb-group-name:read-attribute(name=active) { "outcome" => "success", "result" => false } ---- To make it active again, write the attribute with a true value: [source,ruby] ---- [standalone@localhost:9990 /] ./subsystem=ejb3/mdb-delivery-group=mdb-group-name:write-attribute(name=active,value=true) {"outcome" => "success"}   [standalone@localhost:9990 /] ./subsystem=ejb3/mdb-delivery-group=mdb-group-name:read-attribute(name=active) { "outcome" => "success", "result" => true } ---- [[using-delivery-groups]] === Using Delivery Groups To mark that an MDB belongs to a delivery-group, declare so in the jboss-ejb3.xml file: [source,xml] ----   HelloWorldMDB mdb-delivery-group ---- You can also use a wildcard to mark that all MDBs in your application belong to a delivery-group. In the following example, we add all MDBs in the application to group1, except for HelloWorldMDB, that is added to group2: [source,xml] ---- * group1 HelloWorldMDB group2 ---- Another option is to use org.jboss.ejb3.annotation.DeliveryGroup annotation on each MDB class belonging to a group: [source, java] ---- @MessageDriven(name = "HelloWorldQueueMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/HELLOWORLDMDBQueue"), @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })   @DeliveryGroup("group2")   public class HelloWorldMDB implements MessageListener { ... } ---- A MDB cannot belong to more than one delivery group. Also, all the delivery-groups used by an application must be installed in the Wildfly server upon deployment, or the deployment will fail with a message stating that the delivery-group is missing. [[clustered-singleton-delivery]] == Clustered Singleton Delivery Delivery can be marked as singleton in a clustered environment. In this case, only one node in the cluster will have delivery active for that MDB, whereas in all other nodes, delivery will be inactive. This option can be used for applications that are deployed in all nodes of the cluster. Such applications will be active in all nodes of the cluster, except for the MDBs that are marked as clustered singleton. For those MDBs, only one cluster node will be processing their messages. In case that node stops, another node will have delivery activated, guaranteeing that there is always one node processing the messages. This node is what we call the MDB clustered singleton master node. Notice that applications using clustered singleton delivery can only be deployed in clustered Wildfly servers (i.e., servers that are using the ha configuration). To mark delivery as clustered singleton, you can use the jboss-ejb3.xml or the @ClusteredSingleton annotation: * jboss-ejb3.xml: [source,xml] ---- HelloWorldMDB true ---- As in the previous jboss-ejb3.xml examples, a wildcard can be used in the place of the ejb-name to indicate that all MDBs in the application are singleton clustered. * annotation You can use the org.jboss.ejb3.annotation.ClusteredSingleton annotation to mark an MDB as clustered singleton: [source, java] ---- @MessageDriven(name = "HelloWorldQueueMDB", activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/HELLOWORLDMDBQueue"), @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })   @ClusteredSingleton   public class HelloWorldMDB implements MessageListener { ... } ---- [[using-multiple-mdb-delivery-control-mechanisms]] == Using Multiple MDB Delivery Control Mechanisms The previous d eliver y control mechanisms can be used together in a single MDB. In this case, they work as a set of restrictions for delivery to be active in a MDB. For example, if an MDB belongs to a delivery group and is also a clustered singleton MDB, the delivery will be active for that MDB only if the delivery group is active in the cluster node that was elected as the singleton master. Also, if you use jboss-cli to stopDelivery on a MDB that belongs to a delivery group, the MDB will stop receiving messages in case that group was active. If that group was not active, the MDB will continue in the same, inactive state. But, once that group is active, the MDB will not receive messages, unless a startDelivery operation is executed to revert the previously exectued stopDelivery operation. Invoking stopDelivery on an MDB that is marked as clustered singleton will work in a similar way: no visible effect if the current node is not the clustered singleton master; but it will stop delivery of messages for that MDB if the current node is the clustered singleton master. If the current node is not the master, but eventually becomes so, the delivery of messages will not be active for that MDB, unless a startDelivery operation is invoked. In other words, when more than one delivery control mechanism is used in conjunction, they act as a set of restrictions that need all to be true in order for the MDB to receive messages: * *delivery-group + stop-delivery*: the delivery group needs to be active and the delivery needs to be started in order for that MDB to start receiving messages; * *delivery-group + clustered singleton*: the delivery group needs to be active and the current node needs to be the clustered singleton master node in order for that MDB to start receiving messages; * *delivery-group + clustered singleton + stop-delivery*: as above, delivery-group active, current node equals the clustered singleton master node, plus, start-delivery needs to be invoked on that MDB, only with these three factors being true the MDB will start receiving messages.