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