31 import com.sun.xml.internal.ws.api.SOAPVersion; |
31 import com.sun.xml.internal.ws.api.SOAPVersion; |
32 import com.sun.xml.internal.ws.api.WSBinding; |
32 import com.sun.xml.internal.ws.api.WSBinding; |
33 import com.sun.xml.internal.ws.api.addressing.AddressingVersion; |
33 import com.sun.xml.internal.ws.api.addressing.AddressingVersion; |
34 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; |
34 import com.sun.xml.internal.ws.api.addressing.WSEndpointReference; |
35 import com.sun.xml.internal.ws.api.client.WSPortInfo; |
35 import com.sun.xml.internal.ws.api.client.WSPortInfo; |
|
36 import com.sun.xml.internal.ws.api.message.AddressingUtils; |
36 import com.sun.xml.internal.ws.api.message.Attachment; |
37 import com.sun.xml.internal.ws.api.message.Attachment; |
37 import com.sun.xml.internal.ws.api.message.AttachmentSet; |
38 import com.sun.xml.internal.ws.api.message.AttachmentSet; |
38 import com.sun.xml.internal.ws.api.message.Message; |
39 import com.sun.xml.internal.ws.api.message.Message; |
39 import com.sun.xml.internal.ws.api.message.Packet; |
40 import com.sun.xml.internal.ws.api.message.Packet; |
40 import com.sun.xml.internal.ws.api.pipe.Fiber; |
41 import com.sun.xml.internal.ws.api.pipe.Fiber; |
41 import com.sun.xml.internal.ws.api.pipe.Tube; |
42 import com.sun.xml.internal.ws.api.pipe.Tube; |
42 import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor; |
43 import com.sun.xml.internal.ws.api.server.Container; |
|
44 import com.sun.xml.internal.ws.api.server.ContainerResolver; |
43 import com.sun.xml.internal.ws.binding.BindingImpl; |
45 import com.sun.xml.internal.ws.binding.BindingImpl; |
44 import com.sun.xml.internal.ws.client.*; |
46 import com.sun.xml.internal.ws.client.*; |
45 import com.sun.xml.internal.ws.encoding.soap.DeserializationException; |
47 import com.sun.xml.internal.ws.encoding.soap.DeserializationException; |
46 import com.sun.xml.internal.ws.fault.SOAPFaultBuilder; |
48 import com.sun.xml.internal.ws.fault.SOAPFaultBuilder; |
47 import com.sun.xml.internal.ws.message.AttachmentSetImpl; |
49 import com.sun.xml.internal.ws.message.AttachmentSetImpl; |
61 import javax.xml.ws.WebServiceException; |
63 import javax.xml.ws.WebServiceException; |
62 import javax.xml.ws.handler.MessageContext; |
64 import javax.xml.ws.handler.MessageContext; |
63 import javax.xml.ws.http.HTTPBinding; |
65 import javax.xml.ws.http.HTTPBinding; |
64 import javax.xml.ws.soap.SOAPBinding; |
66 import javax.xml.ws.soap.SOAPBinding; |
65 import javax.xml.ws.soap.SOAPFaultException; |
67 import javax.xml.ws.soap.SOAPFaultException; |
66 import javax.xml.ws.WebServiceClient; |
|
67 import javax.xml.ws.WebEndpoint; |
|
68 import java.net.MalformedURLException; |
68 import java.net.MalformedURLException; |
69 import java.net.URI; |
69 import java.net.URI; |
70 import java.net.URISyntaxException; |
70 import java.net.URISyntaxException; |
71 import java.net.URL; |
71 import java.net.URL; |
72 import java.util.ArrayList; |
72 import java.util.ArrayList; |
73 import java.util.HashMap; |
73 import java.util.HashMap; |
74 import java.util.List; |
74 import java.util.List; |
75 import java.util.Map; |
75 import java.util.Map; |
76 import java.util.concurrent.Callable; |
76 import java.util.concurrent.Callable; |
77 import java.util.concurrent.Executor; |
|
78 import java.util.concurrent.ExecutorService; |
|
79 import java.util.concurrent.Future; |
77 import java.util.concurrent.Future; |
80 import java.util.concurrent.TimeUnit; |
|
81 import java.lang.reflect.Method; |
|
82 import java.util.logging.Level; |
78 import java.util.logging.Level; |
83 import java.util.logging.Logger; |
79 import java.util.logging.Logger; |
84 |
80 |
85 |
81 |
86 /** |
82 /** |
150 this.soapVersion = binding.getSOAPVersion(); |
146 this.soapVersion = binding.getSOAPVersion(); |
151 this.allowFaultResponseMsg = allowFaultResponseMsg; |
147 this.allowFaultResponseMsg = allowFaultResponseMsg; |
152 } |
148 } |
153 /** |
149 /** |
154 * |
150 * |
155 * @param port dispatch instance is associated with this wsdl port qName |
151 * @param portportInfo dispatch instance is associated with this wsdl port qName |
156 * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD |
152 * @param mode Service.mode associated with this Dispatch instance - Service.mode.MESSAGE or Service.mode.PAYLOAD |
157 * @param owner Service that created the Dispatch |
|
158 * @param pipe Master pipe for the pipeline |
153 * @param pipe Master pipe for the pipeline |
159 * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP |
154 * @param binding Binding of this Dispatch instance, current one of SOAP/HTTP or XML/HTTP |
160 * @param allowFaultResponseMsg A packet containing a SOAP fault message is allowed as the response to a request on this dispatch instance. |
155 * @param allowFaultResponseMsg A packet containing a SOAP fault message is allowed as the response to a request on this dispatch instance. |
161 */ |
156 */ |
162 protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, Tube pipe, BindingImpl binding, @Nullable WSEndpointReference epr, boolean allowFaultResponseMsg) { |
157 protected DispatchImpl(WSPortInfo portInfo, Service.Mode mode, Tube pipe, BindingImpl binding, @Nullable WSEndpointReference epr, boolean allowFaultResponseMsg) { |
178 * Obtains the value to return from the response message. |
173 * Obtains the value to return from the response message. |
179 */ |
174 */ |
180 abstract T toReturnValue(Packet response); |
175 abstract T toReturnValue(Packet response); |
181 |
176 |
182 public final Response<T> invokeAsync(T param) { |
177 public final Response<T> invokeAsync(T param) { |
183 if (LOGGER.isLoggable(Level.FINE)) { |
178 Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); |
184 dumpParam(param, "invokeAsync(T)"); |
179 try { |
185 } |
180 if (LOGGER.isLoggable(Level.FINE)) { |
186 AsyncInvoker invoker = new DispatchAsyncInvoker(param); |
181 dumpParam(param, "invokeAsync(T)"); |
187 AsyncResponseImpl<T> ft = new AsyncResponseImpl<T>(invoker,null); |
182 } |
188 invoker.setReceiver(ft); |
183 AsyncInvoker invoker = new DispatchAsyncInvoker(param); |
189 ft.run(); |
184 AsyncResponseImpl<T> ft = new AsyncResponseImpl<T>(invoker,null); |
190 return ft; |
185 invoker.setReceiver(ft); |
|
186 ft.run(); |
|
187 return ft; |
|
188 } finally { |
|
189 ContainerResolver.getDefault().exitContainer(old); |
|
190 } |
191 } |
191 } |
192 |
192 |
193 private void dumpParam(T param, String method) { |
193 private void dumpParam(T param, String method) { |
194 if (param instanceof Packet) { |
194 if (param instanceof Packet) { |
195 Packet message = (Packet)param; |
195 Packet message = (Packet)param; |
199 if (LOGGER.isLoggable(Level.FINE)) { |
199 if (LOGGER.isLoggable(Level.FINE)) { |
200 AddressingVersion av = DispatchImpl.this.getBinding().getAddressingVersion(); |
200 AddressingVersion av = DispatchImpl.this.getBinding().getAddressingVersion(); |
201 SOAPVersion sv = DispatchImpl.this.getBinding().getSOAPVersion(); |
201 SOAPVersion sv = DispatchImpl.this.getBinding().getSOAPVersion(); |
202 action = |
202 action = |
203 av != null && message.getMessage() != null ? |
203 av != null && message.getMessage() != null ? |
204 message.getMessage().getHeaders().getAction(av, sv) : null; |
204 AddressingUtils.getAction(message.getMessage().getHeaders(), av, sv) : null; |
205 msgId = |
205 msgId = |
206 av != null && message.getMessage() != null ? |
206 av != null && message.getMessage() != null ? |
207 message.getMessage().getHeaders().getMessageID(av, sv) : null; |
207 AddressingUtils.getMessageID(message.getMessage().getHeaders(), av, sv) : null; |
208 LOGGER.fine("In DispatchImpl." + method + " for message with action: " + action + " and msg ID: " + msgId + " msg: " + message.getMessage()); |
208 LOGGER.fine("In DispatchImpl." + method + " for message with action: " + action + " and msg ID: " + msgId + " msg: " + message.getMessage()); |
209 |
209 |
210 if (message.getMessage() == null) { |
210 if (message.getMessage() == null) { |
211 LOGGER.fine("Dispatching null message for action: " + action + " and msg ID: " + msgId); |
211 LOGGER.fine("Dispatching null message for action: " + action + " and msg ID: " + msgId); |
212 } |
212 } |
213 } |
213 } |
214 } |
214 } |
215 } |
215 } |
216 public final Future<?> invokeAsync(T param, AsyncHandler<T> asyncHandler) { |
216 public final Future<?> invokeAsync(T param, AsyncHandler<T> asyncHandler) { |
217 if (LOGGER.isLoggable(Level.FINE)) { |
217 Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); |
218 dumpParam(param, "invokeAsync(T, AsyncHandler<T>)"); |
218 try { |
219 } |
219 if (LOGGER.isLoggable(Level.FINE)) { |
220 AsyncInvoker invoker = new DispatchAsyncInvoker(param); |
220 dumpParam(param, "invokeAsync(T, AsyncHandler<T>)"); |
221 AsyncResponseImpl<T> ft = new AsyncResponseImpl<T>(invoker,asyncHandler); |
221 } |
222 invoker.setReceiver(ft); |
222 AsyncInvoker invoker = new DispatchAsyncInvoker(param); |
223 invoker.setNonNullAsyncHandlerGiven(asyncHandler != null); |
223 AsyncResponseImpl<T> ft = new AsyncResponseImpl<T>(invoker,asyncHandler); |
224 |
224 invoker.setReceiver(ft); |
225 ft.run(); |
225 invoker.setNonNullAsyncHandlerGiven(asyncHandler != null); |
226 return ft; |
226 |
|
227 ft.run(); |
|
228 return ft; |
|
229 } finally { |
|
230 ContainerResolver.getDefault().exitContainer(old); |
|
231 } |
227 } |
232 } |
228 |
233 |
229 /** |
234 /** |
230 * Synchronously invokes a service. |
235 * Synchronously invokes a service. |
231 * |
236 * |
237 try { |
242 try { |
238 try { |
243 try { |
239 checkNullAllowed(in, rc, binding, mode); |
244 checkNullAllowed(in, rc, binding, mode); |
240 |
245 |
241 Packet message = createPacket(in); |
246 Packet message = createPacket(in); |
|
247 message.setState(Packet.State.ClientRequest); |
242 resolveEndpointAddress(message, rc); |
248 resolveEndpointAddress(message, rc); |
243 setProperties(message,true); |
249 setProperties(message,true); |
244 response = process(message,rc,receiver); |
250 response = process(message,rc,receiver); |
245 Message msg = response.getMessage(); |
251 Message msg = response.getMessage(); |
246 |
252 |
272 response.transportBackChannel.close(); |
278 response.transportBackChannel.close(); |
273 } |
279 } |
274 } |
280 } |
275 |
281 |
276 public final T invoke(T in) { |
282 public final T invoke(T in) { |
277 if (LOGGER.isLoggable(Level.FINE)) { |
283 Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); |
278 dumpParam(in, "invoke(T)"); |
284 try { |
279 } |
285 if (LOGGER.isLoggable(Level.FINE)) { |
280 |
286 dumpParam(in, "invoke(T)"); |
281 return doInvoke(in,requestContext,this); |
287 } |
|
288 |
|
289 return doInvoke(in,requestContext,this); |
|
290 } finally { |
|
291 ContainerResolver.getDefault().exitContainer(old); |
|
292 } |
282 } |
293 } |
283 |
294 |
284 public final void invokeOneWay(T in) { |
295 public final void invokeOneWay(T in) { |
285 if (LOGGER.isLoggable(Level.FINE)) { |
296 Container old = ContainerResolver.getDefault().enterContainer(owner.getContainer()); |
286 dumpParam(in, "invokeOneWay(T)"); |
|
287 } |
|
288 |
|
289 try { |
297 try { |
290 checkNullAllowed(in, requestContext, binding, mode); |
298 if (LOGGER.isLoggable(Level.FINE)) { |
291 |
299 dumpParam(in, "invokeOneWay(T)"); |
292 Packet request = createPacket(in); |
300 } |
293 setProperties(request,false); |
301 |
294 Packet response = process(request,requestContext,this); |
302 try { |
295 } catch(WebServiceException e){ |
303 checkNullAllowed(in, requestContext, binding, mode); |
296 //it could be a WebServiceException or a ProtocolException |
304 |
297 throw e; |
305 Packet request = createPacket(in); |
298 } catch(Throwable e){ |
306 request.setState(Packet.State.ClientRequest); |
299 // it could be a RuntimeException resulting due to some internal bug or |
307 setProperties(request,false); |
300 // its some other exception resulting from user error, wrap it in |
308 process(request,requestContext,this); |
301 // WebServiceException |
309 } catch(WebServiceException e){ |
302 throw new WebServiceException(e); |
310 //it could be a WebServiceException or a ProtocolException |
|
311 throw e; |
|
312 } catch(Throwable e){ |
|
313 // it could be a RuntimeException resulting due to some internal bug or |
|
314 // its some other exception resulting from user error, wrap it in |
|
315 // WebServiceException |
|
316 throw new WebServiceException(e); |
|
317 } |
|
318 } finally { |
|
319 ContainerResolver.getDefault().exitContainer(old); |
303 } |
320 } |
304 } |
321 } |
305 |
322 |
306 void setProperties(Packet packet, boolean expectReply) { |
323 void setProperties(Packet packet, boolean expectReply) { |
307 packet.expectReply = expectReply; |
324 packet.expectReply = expectReply; |
356 |
373 |
357 public final @NotNull QName getPortName() { |
374 public final @NotNull QName getPortName() { |
358 return portname; |
375 return portname; |
359 } |
376 } |
360 |
377 |
361 void resolveEndpointAddress(@NotNull Packet message, @NotNull RequestContext requestContext) { |
378 void resolveEndpointAddress(@NotNull final Packet message, @NotNull final RequestContext requestContext) { |
|
379 final boolean p = message.packetTakesPriorityOverRequestContext; |
|
380 |
362 //resolve endpoint look for query parameters, pathInfo |
381 //resolve endpoint look for query parameters, pathInfo |
363 String endpoint = (String) requestContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); |
382 String endpoint; |
|
383 if (p && message.endpointAddress != null) { |
|
384 endpoint = message.endpointAddress.toString(); |
|
385 } else { |
|
386 endpoint = (String) requestContext.get(BindingProvider.ENDPOINT_ADDRESS_PROPERTY); |
|
387 } |
|
388 // This is existing before packetTakesPriorityOverRequestContext so leaving in place. |
364 if (endpoint == null) |
389 if (endpoint == null) |
365 endpoint = message.endpointAddress.toString(); |
390 endpoint = message.endpointAddress.toString(); |
366 |
391 |
367 String pathInfo = null; |
392 String pathInfo = null; |
368 String queryString = null; |
393 String queryString = null; |
369 if (requestContext.get(MessageContext.PATH_INFO) != null) |
394 if (p && message.invocationProperties.get(MessageContext.PATH_INFO) != null) { |
|
395 pathInfo = (String) message.invocationProperties.get(MessageContext.PATH_INFO); |
|
396 } else if (requestContext.get(MessageContext.PATH_INFO) != null) { |
370 pathInfo = (String) requestContext.get(MessageContext.PATH_INFO); |
397 pathInfo = (String) requestContext.get(MessageContext.PATH_INFO); |
371 |
398 } |
372 if (requestContext.get(MessageContext.QUERY_STRING) != null) |
399 |
|
400 if (p && message.invocationProperties.get(MessageContext.QUERY_STRING) != null) { |
|
401 queryString = (String) message.invocationProperties.get(MessageContext.QUERY_STRING); |
|
402 } else if (requestContext.get(MessageContext.QUERY_STRING) != null) { |
373 queryString = (String) requestContext.get(MessageContext.QUERY_STRING); |
403 queryString = (String) requestContext.get(MessageContext.QUERY_STRING); |
374 |
404 } |
375 |
405 |
376 String resolvedEndpoint = null; |
|
377 if (pathInfo != null || queryString != null) { |
406 if (pathInfo != null || queryString != null) { |
378 pathInfo = checkPath(pathInfo); |
407 pathInfo = checkPath(pathInfo); |
379 queryString = checkQuery(queryString); |
408 queryString = checkQuery(queryString); |
380 if (endpoint != null) { |
409 if (endpoint != null) { |
381 try { |
410 try { |
382 final URI endpointURI = new URI(endpoint); |
411 final URI endpointURI = new URI(endpoint); |
383 resolvedEndpoint = resolveURI(endpointURI, pathInfo, queryString); |
412 endpoint = resolveURI(endpointURI, pathInfo, queryString); |
384 } catch (URISyntaxException e) { |
413 } catch (URISyntaxException e) { |
385 throw new WebServiceException(DispatchMessages.INVALID_URI(endpoint)); |
414 throw new WebServiceException(DispatchMessages.INVALID_URI(endpoint)); |
386 } |
415 } |
387 } |
416 } |
388 requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, resolvedEndpoint); |
417 } |
389 //message.endpointAddress = EndpointAddress.create(resolvedEndpoint); |
418 // These two lines used to be inside the above if. It is outside so: |
390 } |
419 // - in cases where there is no setting of address on a Packet before invocation or no pathInfo/queryString |
|
420 // this will just put back what it found in the requestContext - basically a noop. |
|
421 // - but when info is in the Packet this will update so it will get used later. |
|
422 // Remember - we are operating on a copied RequestContext at this point - not the sticky one in the Stub. |
|
423 requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, endpoint); |
|
424 // This is not necessary because a later step will copy the resolvedEndpoint put above into message. |
|
425 //message.endpointAddress = EndpointAddress.create(endpoint); |
391 } |
426 } |
392 |
427 |
393 protected @NotNull String resolveURI(@NotNull URI endpointURI, @Nullable String pathInfo, @Nullable String queryString) { |
428 protected @NotNull String resolveURI(@NotNull URI endpointURI, @Nullable String pathInfo, @Nullable String queryString) { |
394 String query = null; |
429 String query = null; |
395 String fragment = null; |
430 String fragment = null; |
519 } |
554 } |
520 |
555 |
521 public void do_run () { |
556 public void do_run () { |
522 checkNullAllowed(param, rc, binding, mode); |
557 checkNullAllowed(param, rc, binding, mode); |
523 final Packet message = createPacket(param); |
558 final Packet message = createPacket(param); |
|
559 message.setState(Packet.State.ClientRequest); |
524 message.nonNullAsyncHandlerGiven = this.nonNullAsyncHandlerGiven; |
560 message.nonNullAsyncHandlerGiven = this.nonNullAsyncHandlerGiven; |
525 resolveEndpointAddress(message, rc); |
561 resolveEndpointAddress(message, rc); |
526 setProperties(message,true); |
562 setProperties(message,true); |
527 |
563 |
528 String action = null; |
564 String action = null; |
530 if (LOGGER.isLoggable(Level.FINE)) { |
566 if (LOGGER.isLoggable(Level.FINE)) { |
531 AddressingVersion av = DispatchImpl.this.getBinding().getAddressingVersion(); |
567 AddressingVersion av = DispatchImpl.this.getBinding().getAddressingVersion(); |
532 SOAPVersion sv = DispatchImpl.this.getBinding().getSOAPVersion(); |
568 SOAPVersion sv = DispatchImpl.this.getBinding().getSOAPVersion(); |
533 action = |
569 action = |
534 av != null && message.getMessage() != null ? |
570 av != null && message.getMessage() != null ? |
535 message.getMessage().getHeaders().getAction(av, sv) : null; |
571 AddressingUtils.getAction(message.getMessage().getHeaders(), av, sv) : null; |
536 msgId = |
572 msgId = |
537 av != null&& message.getMessage() != null ? |
573 av != null&& message.getMessage() != null ? |
538 message.getMessage().getHeaders().getMessageID(av, sv) : null; |
574 AddressingUtils.getMessageID(message.getMessage().getHeaders(), av, sv) : null; |
539 LOGGER.fine("In DispatchAsyncInvoker.do_run for async message with action: " + action + " and msg ID: " + msgId); |
575 LOGGER.fine("In DispatchAsyncInvoker.do_run for async message with action: " + action + " and msg ID: " + msgId); |
540 } |
576 } |
541 |
577 |
542 final String actionUse = action; |
578 final String actionUse = action; |
543 final String msgIdUse = msgId; |
579 final String msgIdUse = msgId; |