1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing.inbound;
12
13 import org.mule.api.MessagingException;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.lifecycle.InitialisationException;
16 import org.mule.api.routing.RoutingException;
17 import org.mule.api.store.ObjectStore;
18 import org.mule.config.i18n.CoreMessages;
19 import org.mule.util.expression.ExpressionEvaluatorManager;
20 import org.mule.util.store.InMemoryObjectStore;
21
22
23
24
25
26
27
28
29
30 public class IdempotentReceiver extends SelectiveConsumer
31 {
32 protected volatile ObjectStore store;
33 protected volatile String assignedComponentName;
34
35 protected String idExpression = "${message:id}";
36
37 public IdempotentReceiver()
38 {
39 super();
40 }
41
42 protected void initialize(MuleEvent event) throws RoutingException
43 {
44 if (assignedComponentName == null && store == null)
45 {
46 this.assignedComponentName = event.getService().getName();
47 try
48 {
49 this.store = this.createMessageIdStore();
50 }
51 catch (InitialisationException e)
52 {
53 throw new RoutingException(event.getMessage(), event.getEndpoint(), e);
54 }
55 }
56 }
57
58 protected ObjectStore createMessageIdStore() throws InitialisationException
59 {
60 InMemoryObjectStore s = new InMemoryObjectStore();
61 s.setName(assignedComponentName);
62 s.setMaxEntries(-1);
63 s.setEntryTTL(60 * 5);
64 s.setExpirationInterval(6000);
65 s.initialise();
66 return s;
67 }
68
69
70 public boolean isMatch(MuleEvent event) throws MessagingException
71 {
72 if (!super.isMatch(event))
73 {
74 return false;
75 }
76 else
77 {
78 if (store == null)
79 {
80
81
82 synchronized (this)
83 {
84 this.initialize(event);
85 }
86 }
87
88 try
89 {
90 return !store.containsObject(this.getIdForEvent(event));
91 }
92 catch (Exception ex)
93 {
94 throw new RoutingException(event.getMessage(), event.getEndpoint(), ex);
95 }
96 }
97 }
98
99
100 public MuleEvent[] process(MuleEvent event) throws MessagingException
101 {
102 String eventComponentName = event.getService().getName();
103 if (!assignedComponentName.equals(eventComponentName))
104 {
105 IllegalArgumentException iex = new IllegalArgumentException(
106 "This receiver is assigned to service: " + assignedComponentName
107 + " but has received an event for service: " + eventComponentName
108 + ". Please check your config to make sure each service"
109 + "has its own instance of IdempotentReceiver.");
110 throw new RoutingException(event.getMessage(), event.getEndpoint(), iex);
111 }
112
113 String id = this.getIdForEvent(event);
114
115 try
116 {
117 if (store.storeObject(id, id))
118 {
119 return new MuleEvent[]{event};
120 }
121 else
122 {
123 return null;
124 }
125 }
126 catch (Exception e)
127 {
128 throw new RoutingException(CoreMessages.failedToWriteMessageToStore(id, assignedComponentName),
129 event.getMessage(), event.getEndpoint(), e);
130 }
131 }
132
133 protected String getIdForEvent(MuleEvent event) throws MessagingException
134 {
135 return ExpressionEvaluatorManager.parse(idExpression, event.getMessage(), true);
136 }
137
138 public String getIdExpression()
139 {
140 return idExpression;
141 }
142
143 public void setIdExpression(String idExpression)
144 {
145 this.idExpression = idExpression;
146 }
147
148 public ObjectStore getStore()
149 {
150 return store;
151 }
152
153 public void setStore(ObjectStore store)
154 {
155 this.store = store;
156 }
157 }