1
2
3
4
5
6
7
8
9
10 package org.mule.transport.ajax.embedded;
11
12 import org.mule.api.MuleContext;
13 import org.mule.api.MuleException;
14 import org.mule.api.construct.FlowConstruct;
15 import org.mule.api.endpoint.EndpointBuilder;
16 import org.mule.api.endpoint.ImmutableEndpoint;
17 import org.mule.api.endpoint.InboundEndpoint;
18 import org.mule.api.lifecycle.InitialisationException;
19 import org.mule.api.transport.MessageReceiver;
20 import org.mule.api.transport.ReplyToHandler;
21 import org.mule.transport.ajax.AjaxMessageReceiver;
22 import org.mule.transport.ajax.AjaxMuleMessageFactory;
23 import org.mule.transport.ajax.AjaxReplyToHandler;
24 import org.mule.transport.ajax.BayeuxAware;
25 import org.mule.transport.ajax.container.MuleAjaxServlet;
26 import org.mule.transport.ajax.i18n.AjaxMessages;
27 import org.mule.transport.servlet.JarResourceServlet;
28 import org.mule.transport.servlet.MuleServletContextListener;
29 import org.mule.transport.servlet.jetty.JettyHttpsConnector;
30 import org.mule.util.StringUtils;
31
32 import java.net.URL;
33 import java.util.Map;
34
35 import javax.servlet.Servlet;
36
37 import org.mortbay.cometd.AbstractBayeux;
38 import org.mortbay.cometd.continuation.ContinuationCometdServlet;
39 import org.mortbay.jetty.AbstractConnector;
40 import org.mortbay.jetty.Connector;
41 import org.mortbay.jetty.handler.ContextHandlerCollection;
42 import org.mortbay.jetty.nio.SelectChannelConnector;
43 import org.mortbay.jetty.servlet.Context;
44 import org.mortbay.jetty.servlet.DefaultServlet;
45 import org.mortbay.jetty.servlet.ServletHolder;
46
47
48
49
50
51
52
53
54
55 public class AjaxConnector extends JettyHttpsConnector implements BayeuxAware
56 {
57 public static final String PROTOCOL = "ajax";
58
59 public static final String CHANNEL_PROPERTY = "channel";
60
61 public static final String AJAX_PATH_SPEC = "/ajax/*";
62
63 public static final String COMETD_CLIENT = "cometd.client";
64
65
66
67
68
69 public static final String REPLYTO_PARAM = "replyTo";
70
71 private URL serverUrl;
72
73
74
75
76
77 private int interval = INT_VALUE_NOT_SET;
78
79
80
81
82
83 private int maxInterval = INT_VALUE_NOT_SET;
84
85
86
87
88
89 private int multiFrameInterval = INT_VALUE_NOT_SET;
90
91
92
93
94 private int logLevel = INT_VALUE_NOT_SET;
95
96
97
98
99
100 private int timeout = INT_VALUE_NOT_SET;
101
102
103
104
105
106 private boolean jsonCommented = true;
107
108
109
110
111
112 private String filters;
113
114
115
116
117
118 private boolean requestAvailable = true;
119
120
121
122
123
124 private boolean directDeliver = true;
125
126
127
128
129
130
131 private int refsThreshold = INT_VALUE_NOT_SET;
132
133 private ContinuationCometdServlet servlet;
134
135 private String resourceBase;
136
137 public AjaxConnector(MuleContext context)
138 {
139 super(context);
140 unregisterSupportedProtocol("http");
141 unregisterSupportedProtocol("https");
142 unregisterSupportedProtocol("jetty-ssl");
143 unregisterSupportedProtocol("jetty");
144 setInitialStateStopped(true);
145 }
146
147 @Override
148 public String getProtocol()
149 {
150 return PROTOCOL;
151 }
152
153 public URL getServerUrl()
154 {
155 return serverUrl;
156 }
157
158 public void setServerUrl(URL serverUrl)
159 {
160 this.serverUrl = serverUrl;
161 }
162
163 @Override
164 protected void doInitialise() throws InitialisationException
165 {
166 if (serverUrl==null)
167 {
168 throw new InitialisationException(AjaxMessages.serverUrlNotDefined(), this);
169 }
170 super.doInitialise();
171 try
172 {
173 createEmbeddedServer();
174 }
175 catch (Exception e)
176 {
177 throw new InitialisationException(e, this);
178 }
179 }
180
181 @Override
182 protected void doStart() throws MuleException
183 {
184 super.doStart();
185 for (MessageReceiver receiver : receivers.values())
186 {
187 ((AjaxMessageReceiver)receiver).setBayeux(getBayeux());
188 }
189 }
190
191 @Override
192 protected void validateSslConfig() throws InitialisationException
193 {
194 if (serverUrl.getProtocol().equals("https"))
195 {
196 super.validateSslConfig();
197 }
198 }
199
200 @Override
201 public ReplyToHandler getReplyToHandler(ImmutableEndpoint endpoint)
202 {
203 return new AjaxReplyToHandler(getDefaultResponseTransformers(endpoint), this);
204 }
205
206 void createEmbeddedServer() throws MuleException
207 {
208 Connector connector = createJettyConnector();
209
210 connector.setPort(serverUrl.getPort());
211 connector.setHost(serverUrl.getHost());
212
213 getHttpServer().addConnector(connector);
214 EndpointBuilder builder = muleContext.getRegistry().lookupEndpointFactory().getEndpointBuilder(serverUrl.toString());
215
216 servlet = (ContinuationCometdServlet)createServlet(connector, builder.buildInboundEndpoint());
217 }
218
219 @Override
220 public Servlet createServlet(Connector connector, ImmutableEndpoint endpoint)
221 {
222 ContinuationCometdServlet ajaxServlet = new MuleAjaxServlet();
223
224 String path = endpoint.getEndpointURI().getPath();
225 if (StringUtils.isBlank(path))
226 {
227 path = ROOT;
228 }
229
230 ContextHandlerCollection handlerCollection = new ContextHandlerCollection();
231 Context root = new Context(handlerCollection, ROOT, Context.NO_SECURITY);
232 root.setConnectorNames(new String[]{connector.getName()});
233 root.addEventListener(new MuleServletContextListener(muleContext, getName()));
234
235 if (!ROOT.equals(path))
236 {
237 Context resourceContext = new Context(handlerCollection, path, Context.NO_SECURITY);
238 populateContext(resourceContext);
239
240 }
241 else
242 {
243 populateContext(root);
244 }
245
246
247 ServletHolder holder = new ServletHolder();
248 holder.setServlet(ajaxServlet);
249 root.addServlet(holder, AJAX_PATH_SPEC);
250
251 if (getInterval() != INT_VALUE_NOT_SET) holder.setInitParameter("interval", Integer.toString(getInterval()));
252 holder.setInitParameter("JSONCommented", Boolean.toString(isJsonCommented()));
253 if (getLogLevel() != INT_VALUE_NOT_SET) holder.setInitParameter("logLevel", Integer.toString(getLogLevel()));
254 if (getMaxInterval() != INT_VALUE_NOT_SET) holder.setInitParameter("maxInterval", Integer.toString(getMaxInterval()));
255 if (getMultiFrameInterval() != INT_VALUE_NOT_SET) holder.setInitParameter("multiFrameInterval", (Integer.toString(getMultiFrameInterval())));
256 if (getTimeout() != INT_VALUE_NOT_SET) holder.setInitParameter("timeout", Integer.toString(getTimeout()));
257 if (getRefsThreshold() != INT_VALUE_NOT_SET) holder.setInitParameter("refsThreshold", Integer.toString(getRefsThreshold()));
258 holder.setInitParameter("requestAvailable", Boolean.toString(isRequestAvailable()));
259
260
261 this.getHttpServer().addHandler(handlerCollection);
262 return ajaxServlet;
263 }
264
265 protected void populateContext(Context context)
266 {
267 context.addServlet(DefaultServlet.class, ROOT);
268 context.addServlet(JarResourceServlet.class, JarResourceServlet.DEFAULT_PATH_SPEC);
269
270 String base = getResourceBase();
271 if (base != null)
272 {
273 context.setResourceBase(base);
274 }
275 }
276
277 @Override
278 protected AbstractConnector createJettyConnector()
279 {
280 if (serverUrl.getProtocol().equals("https"))
281 {
282 return super.createJettyConnector();
283 }
284 else
285 {
286 return new SelectChannelConnector();
287 }
288 }
289
290 public AbstractBayeux getBayeux( )
291 {
292 return servlet.getBayeux();
293 }
294
295 public void setBayeux(AbstractBayeux bayeux)
296 {
297
298 }
299
300 @Override
301 protected MessageReceiver createReceiver(FlowConstruct flowConstruct, InboundEndpoint endpoint) throws Exception
302 {
303 MessageReceiver receiver = getServiceDescriptor().createMessageReceiver(this, flowConstruct, endpoint);
304
305 ((AjaxMessageReceiver) receiver).setBayeux(getBayeux());
306 return receiver;
307 }
308
309 public String getResourceBase()
310 {
311 return resourceBase;
312 }
313
314 public void setResourceBase(String resourceBase)
315 {
316 this.resourceBase = resourceBase;
317 }
318
319 public int getInterval()
320 {
321 return interval;
322 }
323
324 public void setInterval(int interval)
325 {
326 this.interval = interval;
327 }
328
329 public int getMaxInterval()
330 {
331 return maxInterval;
332 }
333
334 public void setMaxInterval(int maxInterval)
335 {
336 this.maxInterval = maxInterval;
337 }
338
339 public int getMultiFrameInterval()
340 {
341 return multiFrameInterval;
342 }
343
344 public void setMultiFrameInterval(int multiFrameInterval)
345 {
346 this.multiFrameInterval = multiFrameInterval;
347 }
348
349 public int getLogLevel()
350 {
351 return logLevel;
352 }
353
354 public void setLogLevel(int logLevel)
355 {
356 this.logLevel = logLevel;
357 }
358
359 public int getTimeout()
360 {
361 return timeout;
362 }
363
364 public void setTimeout(int timeout)
365 {
366 this.timeout = timeout;
367 }
368
369 public boolean isJsonCommented()
370 {
371 return jsonCommented;
372 }
373
374 public void setJsonCommented(boolean jsonCommented)
375 {
376 this.jsonCommented = jsonCommented;
377 }
378
379 public String getFilters()
380 {
381 return filters;
382 }
383
384 public void setFilters(String filters)
385 {
386 this.filters = filters;
387 }
388
389 public boolean isRequestAvailable()
390 {
391 return requestAvailable;
392 }
393
394 public void setRequestAvailable(boolean requestAvailable)
395 {
396 this.requestAvailable = requestAvailable;
397 }
398
399 public boolean isDirectDeliver()
400 {
401 return directDeliver;
402 }
403
404 public void setDirectDeliver(boolean directDeliver)
405 {
406 this.directDeliver = directDeliver;
407 }
408
409 public int getRefsThreshold()
410 {
411 return refsThreshold;
412 }
413
414 public void setRefsThreshold(int refsThreshold)
415 {
416 this.refsThreshold = refsThreshold;
417 }
418 }