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