KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > webservice > EjbWebServiceDispatcher


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.webservice;
24
25 import java.util.Enumeration JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.Date JavaDoc;
28
29 import java.io.InputStream JavaDoc;
30 import java.io.OutputStream JavaDoc;
31 import java.io.IOException JavaDoc;
32 import java.io.ByteArrayOutputStream JavaDoc;
33 import java.io.ByteArrayInputStream JavaDoc;
34 import java.io.OutputStreamWriter JavaDoc;
35 import javax.servlet.http.HttpServletRequest JavaDoc;
36 import javax.servlet.http.HttpServletResponse JavaDoc;
37 import javax.xml.soap.MimeHeaders JavaDoc;
38 import javax.xml.soap.MimeHeader JavaDoc;
39 import javax.xml.soap.SOAPMessage JavaDoc;
40 import javax.xml.soap.SOAPException JavaDoc;
41
42 import javax.xml.namespace.QName JavaDoc;
43 import com.sun.xml.messaging.saaj.util.ByteInputStream;
44 import com.sun.xml.rpc.spi.JaxRpcObjectFactory;
45 import com.sun.xml.rpc.spi.runtime.SOAPMessageContext;
46 import com.sun.xml.rpc.spi.runtime.Handler;
47 import com.sun.xml.rpc.spi.runtime.SOAPConstants;
48 import com.sun.xml.rpc.spi.runtime.StreamingHandler;
49
50 import com.sun.enterprise.deployment.WebServiceEndpoint;
51
52 import com.sun.enterprise.security.jauth.ServerAuthConfig;
53 import com.sun.enterprise.security.wss.WebServiceSecurity;
54 import com.sun.enterprise.security.jauth.ServerAuthContext;
55
56 import com.sun.enterprise.webservice.monitoring.WebServiceEngineImpl;
57 import com.sun.enterprise.webservice.monitoring.EndpointImpl;
58 import com.sun.enterprise.webservice.monitoring.JAXRPCEndpointImpl;
59 import com.sun.enterprise.webservice.monitoring.HttpRequestInfoImpl;
60 import com.sun.enterprise.webservice.monitoring.HttpResponseInfoImpl;
61 import com.sun.enterprise.webservice.monitoring.ThreadLocalInfo;
62  
63 import javax.security.auth.Subject JavaDoc;
64 import java.util.logging.Logger JavaDoc;
65 import java.util.logging.Level JavaDoc;
66 import com.sun.logging.LogDomains;
67
68 /**
69  * Handles dispatching of ejb web service http invocations.
70  *
71  * @author Kenneth Saks
72  */

73 public class EjbWebServiceDispatcher implements EjbMessageDispatcher {
74
75     private static Logger JavaDoc logger =
76         LogDomains.getLogger(LogDomains.EJB_LOGGER);
77
78     private JaxRpcObjectFactory rpcFactory;
79     private WsUtil wsUtil = new WsUtil();
80     private WebServiceEngineImpl wsEngine;
81
82     // @@@ This should be added to jaxrpc spi, probably within
83
// SOAPConstants.
84
private static final QName JavaDoc FAULT_CODE_CLIENT =
85         new QName JavaDoc(SOAPConstants.URI_ENVELOPE, "Client");
86
87     // @@@ Used to set http servlet response object so that TieBase
88
// will correctly flush response code for one-way operations.
89
// Should be added to SPI
90
private static final String JavaDoc HTTP_SERVLET_RESPONSE =
91         "com.sun.xml.rpc.server.http.HttpServletResponse";
92
93     public EjbWebServiceDispatcher() {
94         rpcFactory = JaxRpcObjectFactory.newInstance();
95         wsEngine = WebServiceEngineImpl.getInstance();
96     }
97
98     public void invoke(HttpServletRequest JavaDoc req,
99                        HttpServletResponse JavaDoc resp,
100                        EjbRuntimeEndpointInfo endpointInfo) {
101
102         String JavaDoc method = req.getMethod();
103         
104         if (logger.isLoggable(Level.FINE)) {
105             logger.log(Level.FINE, "WebServiceDispatcher " + req.getMethod() +
106                    " entering for " + req.getRequestURI() + " and query string " + req.getQueryString());
107         }
108         try {
109             if( method.equals("POST") ) {
110                 
111                 handlePost(req, resp, endpointInfo);
112                 
113             } else if( method.equals("GET") ) {
114                 
115                 handleGet(req, resp, endpointInfo);
116                 
117             } else {
118                 
119                 String JavaDoc errorMessage = "Unsupported method request = ["
120                     + method + "] for endpoint " +
121                     endpointInfo.getEndpoint().getEndpointName() + " at " +
122                     endpointInfo.getEndpointAddressUri();
123                 logger.warning(errorMessage);
124                 wsUtil.writeInvalidMethodType(resp, errorMessage);
125             }
126         } catch(Exception JavaDoc e) {
127             logger.log(Level.WARNING, "ejb endpoint exception", e);
128         }
129     }
130
131     private void handlePost(HttpServletRequest JavaDoc req,
132                             HttpServletResponse JavaDoc resp,
133                             EjbRuntimeEndpointInfo endpointInfo)
134         throws IOException JavaDoc, SOAPException JavaDoc
135     {
136         
137         JAXRPCEndpointImpl endpoint = null;
138         String JavaDoc messageID = null;
139         SOAPMessageContext msgContext = null;
140         
141         try {
142             
143             MimeHeaders JavaDoc headers = wsUtil.getHeaders(req);
144             
145             if (!wsUtil.hasTextXmlContentType(headers)) {
146                 wsUtil.writeInvalidContentType(resp);
147                 
148                 return;
149             }
150             
151             msgContext = rpcFactory.createSOAPMessageContext();
152             SOAPMessage JavaDoc message = createSOAPMessage(req, headers);
153                         
154         ServerAuthContext sAC = null;
155         boolean wssSucceded = true;
156             
157             if (message != null) {
158                 
159                 msgContext.setMessage(message);
160
161                 // get the endpoint info
162
endpoint = (JAXRPCEndpointImpl) endpointInfo.getEndpoint().getExtraAttribute(EndpointImpl.NAME);
163                 
164                 if (endpoint!=null) {
165                     // first global notification
166
if (wsEngine.hasGlobalMessageListener()) {
167                         messageID = wsEngine.preProcessRequest(endpoint);
168                     }
169                 } else {
170                     logger.fine("Missing internal monitoring info to trace " + req.getRequestURI());
171                 }
172                 
173                 Handler implementor = null;
174                 try {
175                     // Do ejb container pre-invocation and pre-handler
176
// logic
177
implementor = ((Ejb2RuntimeEndpointInfo) endpointInfo).getHandlerImplementor(msgContext);
178
179                     // Set http response object so one-way operations will
180
// response before actual business method invocation.
181
msgContext.setProperty(HTTP_SERVLET_RESPONSE, resp);
182                     
183             ServerAuthConfig authConfig = endpointInfo.getServerAuthConfig();
184             if (authConfig != null) {
185             sAC = authConfig.getAuthContext
186                 ((StreamingHandler)implementor,message);
187             if (sAC != null) {
188                 wssSucceded =
189                 WebServiceSecurity.validateRequest(msgContext,sAC);
190             }
191             }
192
193                     // Trace if necessary
194
if (messageID!=null || (endpoint!=null && endpoint.hasListeners())) {
195                         // create the thread local
196
ThreadLocalInfo threadLocalInfo =
197                             new ThreadLocalInfo(messageID, req);
198
199                         wsEngine.getThreadLocal().set(threadLocalInfo);
200
201                         endpoint.processRequest(msgContext);
202                     }
203                     
204                     // Pass control back to jaxrpc runtime to invoke
205
// any handlers and call the webservice method itself,
206
// which will be flow back into the ejb container.
207
if (wssSucceded) {
208             implementor.handle(msgContext);
209             }
210                     
211                 } finally {
212                     
213                     // Always call release, even if an error happened
214
// during getImplementor(), since some of the
215
// preInvoke steps might have occurred. It's ok
216
// if implementor is null.
217
endpointInfo.releaseImplementor();
218
219                 }
220             } else {
221                 String JavaDoc errorMsg = "null message POSTed to ejb endpoint " +
222                 endpointInfo.getEndpoint().getEndpointName() +
223                 " at " + endpointInfo.getEndpointAddressUri();
224                 logger.fine(errorMsg);
225                 msgContext.writeSimpleErrorResponse
226                 (FAULT_CODE_CLIENT, errorMsg);
227             }
228             
229             if (messageID!=null || endpoint!=null) {
230                 endpoint.processResponse(msgContext);
231             }
232                 
233             SOAPMessage JavaDoc reply = msgContext.getMessage();
234             
235         if (sAC != null && wssSucceded) {
236         WebServiceSecurity.secureResponse(msgContext,sAC);
237         }
238             
239             if (reply.saveRequired()) {
240                 reply.saveChanges();
241             }
242
243             wsUtil.writeReply(resp, msgContext);
244             
245
246         } catch (Throwable JavaDoc e) {
247             
248             String JavaDoc errorMessage = "invocation error on ejb endpoint " +
249             endpointInfo.getEndpoint().getEndpointName() + " at " +
250             endpointInfo.getEndpointAddressUri();
251             logger.log(Level.WARNING, errorMessage, e);
252             
253             SOAPMessageContext errorMsgContext =
254             rpcFactory.createSOAPMessageContext();
255             errorMsgContext.writeSimpleErrorResponse
256             (SOAPConstants.FAULT_CODE_SERVER, errorMessage);
257             
258             resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
259             if (messageID!=null || endpoint!=null) {
260                 endpoint.processResponse(errorMsgContext);
261             }
262             
263             wsUtil.writeReply(resp, errorMsgContext);
264         }
265         
266         // final tracing notification
267
if (messageID!=null) {
268             HttpResponseInfoImpl response = new HttpResponseInfoImpl(resp);
269             wsEngine.postProcessResponse(messageID, response);
270         }
271         
272
273     }
274
275     private void handleGet(HttpServletRequest JavaDoc req,
276                            HttpServletResponse JavaDoc resp,
277                            EjbRuntimeEndpointInfo endpointInfo)
278         throws IOException JavaDoc
279     {
280        
281         wsUtil.handleGet(req, resp, endpointInfo.getEndpoint());
282
283     }
284
285     protected SOAPMessage JavaDoc createSOAPMessage(HttpServletRequest JavaDoc request,
286                                             MimeHeaders JavaDoc headers)
287         throws IOException JavaDoc {
288
289         InputStream JavaDoc is = request.getInputStream();
290         
291         byte[] bytes = readFully(is);
292         int length = request.getContentLength() == -1 ? bytes.length
293             : request.getContentLength();
294         ByteInputStream in = new ByteInputStream(bytes, length);
295
296         SOAPMessageContext msgContext = rpcFactory.createSOAPMessageContext();
297         SOAPMessage JavaDoc message = msgContext.createMessage(headers, in);
298
299         return message;
300     }
301
302     protected byte[] readFully(InputStream JavaDoc istream) throws IOException JavaDoc {
303         ByteArrayOutputStream JavaDoc bout = new ByteArrayOutputStream JavaDoc();
304         byte[] buf = new byte[1024];
305         int num = 0;
306         while( (num = istream.read(buf)) != -1) {
307             bout.write(buf, 0, num);
308         }
309         byte[] ret = bout.toByteArray();
310         return ret;
311     }
312
313    
314
315     
316 }
317
Popular Tags