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