1
2
3
4
5
6
7
8
9
10
11 package org.mule.cache;
12
13 import org.mule.api.MuleEvent;
14 import org.mule.api.MuleException;
15 import org.mule.api.ThreadSafeAccess;
16 import org.mule.api.processor.MessageProcessor;
17 import org.mule.api.routing.filter.Filter;
18 import org.mule.api.store.ObjectAlreadyExistsException;
19 import org.mule.api.store.ObjectDoesNotExistException;
20 import org.mule.api.store.ObjectStore;
21 import org.mule.api.store.ObjectStoreException;
22 import org.mule.cache.filter.ConsumableMuleMessageFilter;
23 import org.mule.cache.keygenerator.KeyGenerator;
24 import org.mule.cache.keygenerator.MD5KeyGenerator;
25 import org.mule.cache.responsegenerator.DefaultResponseGenerator;
26 import org.mule.cache.responsegenerator.ResponseGenerator;
27 import org.mule.util.store.InMemoryObjectStore;
28
29 import java.io.Serializable;
30
31 import org.apache.commons.logging.Log;
32 import org.apache.commons.logging.LogFactory;
33
34
35
36
37
38
39
40
41
42
43 public class ObjectStoreCachingStrategy implements CachingStrategy
44 {
45
46 protected Log logger = LogFactory.getLog(getClass());
47
48 private ObjectStore<MuleEvent> store = new InMemoryObjectStore<MuleEvent>();
49
50 private KeyGenerator keyGenerator = new MD5KeyGenerator();
51
52 private ResponseGenerator responseGenerator = new DefaultResponseGenerator();
53
54 private Filter consumableFilter = new ConsumableMuleMessageFilter();
55
56 private String name;
57
58 public MuleEvent process(MuleEvent request, MessageProcessor messageProcessor) throws MuleException
59 {
60 if (consumableFilter.accept(request.getMessage()))
61 {
62 Serializable key;
63 try
64 {
65 key = keyGenerator.generateKey(request);
66 }
67 catch (Exception e)
68 {
69 logger.warn("Message will be processed without cache: key generation error", e);
70 return messageProcessor.process(request);
71 }
72
73 return processMessageWithCache(key, request, messageProcessor);
74 }
75 else
76 {
77 return messageProcessor.process(request);
78 }
79 }
80
81 private MuleEvent processMessageWithCache(Serializable key, MuleEvent request, MessageProcessor messageProcessor) throws MuleException
82 {
83 MuleEvent cachedResponse = lookupEventInCache(key);
84
85 MuleEvent response;
86
87 if (cachedResponse != null)
88 {
89 response = responseGenerator.create(request, cachedResponse);
90 }
91 else
92 {
93 response = messageProcessor.process(request);
94
95 if (response == null || consumableFilter.accept(response.getMessage()))
96 {
97 MuleEvent responseCopy = response;
98 if (response instanceof ThreadSafeAccess)
99 {
100 responseCopy = (MuleEvent) ((ThreadSafeAccess) response).newThreadCopy();
101 }
102 store(key, responseCopy);
103 }
104 }
105
106 return response;
107 }
108
109 private MuleEvent lookupEventInCache(Serializable key)
110 {
111 MuleEvent event = retrieve(key);
112
113 if (logger.isDebugEnabled())
114 {
115 if (event != null)
116 {
117 logger.debug("Cache hit for key: " + key + " Event: " + event);
118 }
119 else
120 {
121 logger.debug("Cache miss for key: " + key);
122 }
123 }
124
125 return event;
126 }
127
128 protected void store(Serializable key, MuleEvent value)
129 {
130 try
131 {
132 store.store(key, value);
133 }
134 catch (ObjectAlreadyExistsException e)
135 {
136 if (logger.isInfoEnabled())
137 {
138 logger.info("An object with the specified key already exists in the object store (" + key + ")");
139 }
140 }
141 catch (ObjectStoreException e)
142 {
143
144
145
146
147 logger.warn("Unable to store event in cache", e);
148 }
149 }
150
151 protected MuleEvent retrieve(Serializable key)
152 {
153 try
154 {
155 return store.retrieve(key);
156 }
157 catch (ObjectDoesNotExistException e)
158 {
159
160 }
161 catch (ObjectStoreException e)
162 {
163
164
165
166
167 logger.warn("Unable to retrieve object from cache", e);
168 }
169
170 return null;
171 }
172
173 public ObjectStore<MuleEvent> getStore()
174 {
175 return store;
176 }
177
178 public void setStore(ObjectStore<MuleEvent> store)
179 {
180 this.store = store;
181 }
182
183 public KeyGenerator getKeyGenerator()
184 {
185 return keyGenerator;
186 }
187
188 public void setKeyGenerator(KeyGenerator keyGenerator)
189 {
190 this.keyGenerator = keyGenerator;
191 }
192
193 public ResponseGenerator getResponseGenerator()
194 {
195 return responseGenerator;
196 }
197
198 public void setResponseGenerator(ResponseGenerator responseGenerator)
199 {
200 this.responseGenerator = responseGenerator;
201 }
202
203 public Filter getConsumableFilter()
204 {
205 return consumableFilter;
206 }
207
208 public void setConsumableFilter(Filter consumableFilter)
209 {
210 this.consumableFilter = consumableFilter;
211 }
212
213 public String getName()
214 {
215 return name;
216 }
217
218 public void setName(String name)
219 {
220 this.name = name;
221 }
222 }