1
2
3
4
5
6
7
8
9
10
11 package org.mule.util.queue;
12
13 import org.mule.api.MuleContext;
14 import org.mule.api.context.MuleContextAware;
15 import org.mule.api.store.ListableObjectStore;
16 import org.mule.api.store.ObjectStore;
17 import org.mule.api.store.ObjectStoreException;
18 import org.mule.util.UUID;
19 import org.mule.util.xa.AbstractTransactionContext;
20 import org.mule.util.xa.AbstractXAResourceManager;
21 import org.mule.util.xa.ResourceManagerException;
22 import org.mule.util.xa.ResourceManagerSystemException;
23
24 import java.io.Serializable;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30
31 import javax.transaction.xa.XAResource;
32
33
34
35
36
37
38
39 public class TransactionalQueueManager extends AbstractXAResourceManager implements QueueManager, MuleContextAware
40 {
41 private Map<String, QueueInfo> queues = new HashMap<String, QueueInfo>();
42
43 private QueueConfiguration defaultQueueConfiguration;
44 private MuleContext muleContext;
45 private Set<ListableObjectStore> stores = new HashSet<ListableObjectStore>();
46
47 @Override
48 public synchronized QueueSession getQueueSession()
49 {
50 return new TransactionalQueueSession(this, this);
51 }
52
53 @Override
54 public synchronized void setDefaultQueueConfiguration(QueueConfiguration config)
55 {
56 this.defaultQueueConfiguration = config;
57 addStore(config.objectStore);
58 }
59
60 @Override
61 public synchronized void setQueueConfiguration(String queueName, QueueConfiguration config)
62 {
63 getQueue(queueName).setConfig(config);
64 addStore(config.objectStore);
65 }
66
67 protected synchronized QueueInfo getQueue(String name)
68 {
69 QueueInfo q = queues.get(name);
70 if (q == null)
71 {
72 q = new QueueInfo(name, muleContext, defaultQueueConfiguration);
73 queues.put(name, q);
74 }
75 return q;
76 }
77
78 public synchronized QueueInfo getQueueInfo(String name)
79 {
80 QueueInfo q = queues.get(name);
81 return q == null ? q : new QueueInfo(q);
82 }
83
84 @Override
85 protected void doStart() throws ResourceManagerSystemException
86 {
87 findAllStores();
88 for (ListableObjectStore store: stores)
89 {
90 try
91 {
92 store.open();
93 }
94 catch (ObjectStoreException e)
95 {
96 throw new ResourceManagerSystemException(e);
97 }
98 }
99 }
100
101 @Override
102 protected boolean shutdown(int mode, long timeoutMSecs)
103 {
104 findAllStores();
105 for (ListableObjectStore store: stores)
106 {
107 try
108 {
109 store.close();
110 }
111 catch (ObjectStoreException e)
112 {
113
114 logger.error("Error closing persistent store", e);
115 }
116 }
117
118
119 synchronized (this)
120 {
121 queues.clear();
122 }
123 return super.shutdown(mode, timeoutMSecs);
124 }
125
126 @Override
127 protected void recover() throws ResourceManagerSystemException
128 {
129 findAllStores();
130 for (ListableObjectStore store: stores)
131 {
132 try
133 {
134 List<Serializable> keys = store.allKeys();
135 for (Serializable key : keys)
136 {
137 QueueKey queueKey = (QueueKey) key;
138 getQueue(queueKey.queueName).putNow(queueKey.id);
139 }
140 }
141 catch (Exception e)
142 {
143 throw new ResourceManagerSystemException(e);
144 }
145 }
146 }
147
148 @Override
149 protected AbstractTransactionContext createTransactionContext(Object session)
150 {
151 return new QueueTransactionContext(this);
152 }
153
154 @Override
155 protected void doBegin(AbstractTransactionContext context)
156 {
157
158 }
159
160 @Override
161 protected int doPrepare(AbstractTransactionContext context)
162 {
163 return XAResource.XA_OK;
164 }
165
166 @Override
167 protected void doCommit(AbstractTransactionContext context) throws ResourceManagerException
168 {
169 context.doCommit();
170 }
171
172 protected Serializable doStore(QueueInfo queue, Serializable object) throws ObjectStoreException
173 {
174 ObjectStore<Serializable> store = queue.getStore();
175
176 String id = muleContext == null ? UUID.getUUID() : muleContext.getUniqueIdString();
177 Serializable key = new QueueKey(queue.getName(), id);
178 store.store(key, object);
179 return id;
180 }
181
182 protected void doRemove(QueueInfo queue, Serializable id) throws ObjectStoreException
183 {
184 ObjectStore<Serializable> store = queue.getStore();
185
186 Serializable key = new QueueKey(queue.getName(), id);
187 store.remove(key);
188 }
189
190 protected Serializable doLoad(QueueInfo queue, Serializable id) throws ObjectStoreException
191 {
192 ObjectStore<Serializable> store = queue.getStore();
193
194 Serializable key = new QueueKey(queue.getName(), id);
195 return store.retrieve(key);
196 }
197
198 @Override
199 protected void doRollback(AbstractTransactionContext context) throws ResourceManagerException
200 {
201 context.doRollback();
202 }
203
204 protected synchronized void findAllStores()
205 {
206 if (muleContext != null)
207 {
208 for (ListableObjectStore store: muleContext.getRegistry().lookupByType(ListableObjectStore.class).values())
209 {
210 addStore(store);
211 }
212 }
213 }
214
215 @Override
216 public void setMuleContext(MuleContext context)
217 {
218 this.muleContext = context;
219 }
220
221 public MuleContext getMuleContext()
222 {
223 return muleContext;
224 }
225
226 private void addStore(ListableObjectStore<?> store)
227 {
228 stores.add(store);
229 }
230 }