1 24 25 package com.rift.coad.lib.webservice; 27 28 import java.io.ByteArrayOutputStream ; 30 import java.io.ByteArrayInputStream ; 31 import java.io.File ; 32 import java.io.FileInputStream ; 33 import java.io.InputStream ; 34 import java.lang.ClassLoader ; 35 import java.net.InetAddress ; 36 import java.util.Iterator ; 37 import java.util.Map ; 38 import java.util.Vector ; 39 import java.util.Set ; 40 import java.util.regex.Matcher ; 41 import java.util.regex.Pattern ; 42 import javax.xml.namespace.QName ; 43 import java.lang.reflect.Method ; 44 import javax.naming.InitialContext ; 45 import javax.transaction.Status ; 46 import javax.transaction.UserTransaction ; 47 48 49 import org.w3c.dom.Document ; 51 52 import org.apache.log4j.Logger; 54 55 import com.ibm.wsdl.OperationImpl; 57 58 import javax.xml.soap.MimeHeaders ; 60 61 import org.apache.axis.AxisFault; 63 import org.apache.axis.AxisEngine; 64 import org.apache.axis.Constants; 65 import org.apache.axis.Message; 66 import org.apache.axis.MessageContext; 67 import org.apache.axis.constants.Scope; 68 import org.apache.axis.description.ServiceDesc; 69 import org.apache.axis.handlers.soap.SOAPService; 70 import org.apache.axis.message.SOAPEnvelope; 71 import org.apache.axis.message.SOAPFault; 72 import org.apache.axis.providers.java.RPCProvider; 73 import org.apache.axis.transport.http.NonBlockingBufferedInputStream; 74 import org.apache.axis.server.AxisServer; 75 import org.apache.axis.utils.ClassUtils; 76 import org.apache.axis.utils.Messages; 77 import org.apache.axis.utils.XMLUtils; 78 import org.apache.axis.wsdl.gen.Parser; 79 import org.apache.axis.wsdl.symbolTable.SymbolTable; 80 import org.apache.axis.wsdl.symbolTable.BaseType; 81 import org.apache.axis.wsdl.symbolTable.BindingEntry; 82 83 import com.rift.coad.lib.configuration.Configuration; 85 import com.rift.coad.lib.configuration.ConfigurationFactory; 86 import com.rift.coad.lib.deployment.WebServiceInfo; 87 import com.rift.coad.lib.deployment.DeploymentLoader; 88 import com.rift.coad.lib.httpd.HttpDaemon; 89 import com.rift.coad.lib.httpd.MimeTypes; 90 import com.rift.coad.lib.thirdparty.axis.AxisManager; 91 import com.rift.coad.lib.thirdparty.axis.AxisException; 92 93 99 public class WebServiceWrapper { 100 101 protected Logger log = 103 Logger.getLogger(WebServiceWrapper.class.getName()); 104 105 private final static String PARSER_PATTERN = 107 "address[\\s]+location=\"[a-z0-9://_-]*\""; 108 private final static String SERVICE_END_POINT_FORMAT = 109 "address location=\"http://%s:%d%s\""; 110 private final static String URL_FORMAT = 111 "http://%s:%d%s"; 112 private final static String HOST = "host"; 113 private final static String PORT = "port"; 114 private final static String TRANSPORT_NAME = "SimpleHTTP"; 115 116 117 private String serviceEndPoint = null; 119 private String url = null; 120 private String path = null; 121 private String role = null; 122 private SOAPService service = null; 123 private ClassLoader classLoader = null; 124 private boolean transaction = false; 125 private InitialContext context = null; 126 private UserTransaction ut = null; 127 128 136 public WebServiceWrapper(WebServiceInfo webServiceInfo, 137 DeploymentLoader deploymentLoader) 138 throws WebServiceException { 139 140 try { 141 Configuration config = ConfigurationFactory.getInstance(). 142 getConfig(WebServiceWrapper.class); 143 context = new InitialContext (); 144 145 String host = config.getString(HOST, 146 InetAddress.getLocalHost().getCanonicalHostName()); 147 int port = (int)config.getLong(PORT,HttpDaemon.DEFAULT_PORT); 148 149 path = webServiceInfo.getPath(); 150 role = webServiceInfo.getRole(); 151 serviceEndPoint = String.format( 152 SERVICE_END_POINT_FORMAT,host,port,path); 153 url = String.format(URL_FORMAT,host,port,path); 154 155 AxisEngine engine = AxisManager.getInstance().getServer(); 157 158 deploymentLoader.getClass(webServiceInfo.getClassName()); 160 161 service = new SOAPService(new WebServiceInvoker( 163 deploymentLoader.getClassLoader())); 164 165 service.setName(webServiceInfo.getClassName()); 166 service.setOption(RPCProvider.OPTION_CLASSNAME, 167 webServiceInfo.getClassName()); 168 service.setOption(RPCProvider.OPTION_ALLOWEDMETHODS, "*"); 169 service.setOption(RPCProvider.OPTION_SCOPE, 170 Scope.DEFAULT.getName()); 171 172 String wsdlPath = deploymentLoader.getTmpDir().getAbsolutePath() + 174 File.separator + 175 webServiceInfo.getWSDLPath(); 176 validate(wsdlPath,deploymentLoader.getClassLoader().loadClass( 177 webServiceInfo.getClassName())); 178 179 ServiceDesc serviceDesc = service.getServiceDescription(); 181 serviceDesc.setWSDLFile(wsdlPath); 182 183 service.setEngine(engine); 184 service.init(); 185 186 classLoader = deploymentLoader.getClassLoader(); 188 189 ClassUtils.setClassLoader(webServiceInfo.getClassName(), 191 deploymentLoader.getClassLoader()); 192 193 transaction = webServiceInfo.getTransaction(); 194 if (transaction) { 195 ut = (UserTransaction )context.lookup( 196 "java:comp/UserTransaction"); 197 } 198 199 } catch (Exception ex) { 200 throw new WebServiceException( 201 "Failed to initialize the web service : " + ex.getMessage() 202 ,ex); 203 } 204 } 205 206 207 212 public String getPath() { 213 return path; 214 } 215 216 217 222 public String getRole() { 223 return role; 224 } 225 226 227 232 public SOAPService getService() { 233 return service; 234 } 235 236 237 242 public ClassLoader getClassLoader() { 243 return classLoader; 244 } 245 246 247 253 public String generateWSDL() throws 254 WebServiceException { 255 MessageContext msgContext = null; 257 try { 258 msgContext = setupContext(); 259 AxisServer engine = AxisManager.getInstance().getServer(); 260 engine.generateWSDL(msgContext); 261 Document doc = (Document ) msgContext.getProperty("WSDL"); 262 XMLUtils.normalize(doc.getDocumentElement()); 263 String wsdl = XMLUtils.PrettyDocumentToString(doc); 264 Pattern pattern = Pattern.compile(PARSER_PATTERN, 265 Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); 266 return pattern.matcher(wsdl).replaceFirst(serviceEndPoint); 267 } catch (WebServiceException ex) { 268 throw ex; 269 } catch (AxisException ex) { 270 throw new WebServiceException( 271 "Failed to retrieve a valid axis reference : " + 272 ex.getMessage(),ex); 273 } catch (Exception ex) { 274 processException(msgContext,ex); 275 } 276 return null; 280 } 281 282 283 291 public String processRequest(String message) throws WebServiceException { 292 return processRequest(new ByteArrayInputStream (message.getBytes()), 293 new MimeHeaders ()); 294 } 295 296 297 306 public String processRequest(InputStream in, MimeHeaders headers) throws 307 WebServiceException { 308 MessageContext msgContext = null; 309 boolean ownTransaction = false; 310 try { 311 if (transaction && 312 (ut.getStatus() == Status.STATUS_NO_TRANSACTION)) { 313 ut.begin(); 314 ownTransaction = true; 315 } 316 msgContext = setupContext(); 317 AxisServer engine = AxisManager.getInstance().getServer(); 318 NonBlockingBufferedInputStream inputStream = new 319 NonBlockingBufferedInputStream(); 320 inputStream.setInputStream(in); 321 322 Message requestMsg = new Message(inputStream,false,headers); 324 msgContext.setRequestMessage(requestMsg); 325 326 engine.invoke(msgContext); 328 329 Message responseMsg = msgContext.getResponseMessage(); 331 ByteArrayOutputStream output = new ByteArrayOutputStream (); 332 responseMsg.writeTo(output); 333 output.flush(); 334 if (ownTransaction) { 335 ut.commit(); 336 ownTransaction = false; 337 } 338 return output.toString(); 339 } catch (WebServiceException ex) { 340 throw ex; 341 } catch (Exception ex) { 342 processException(msgContext,ex); 343 } finally { 344 if (ownTransaction) { 345 try { 346 if (ut.getStatus() == Status.STATUS_ACTIVE) { 347 ut.rollback(); 348 } 349 } catch (Exception ex2) { 350 log.error("Failed to rollback the changes : " + 351 ex2.getMessage(),ex2); 352 } 353 } 354 } 355 356 return null; 360 } 361 362 369 private void validate(String wsdlPath,Class ref) throws WebServiceException { 370 try { 371 374 Parser parser = new Parser(); 375 parser.run(wsdlPath); 376 Set operations = getOpertations(parser); 377 Method [] methods = ref.getDeclaredMethods(); 378 for (Iterator iter = operations.iterator(); iter.hasNext();) { 379 OperationImpl operation = (OperationImpl)iter.next(); 380 boolean found = false; 381 for (int index = 0; index < methods.length; index++) { 382 if (methods[index].getName().equals(operation.getName())) { 383 found = true; 384 } 385 } 386 if (!found) { 387 throw new WebServiceException("The operation [" + 388 operation.getName() + "] not found on [" + 389 ref.getName() + "]"); 390 } 391 } 392 } catch (WebServiceException ex) { 393 throw ex; 394 } catch (Exception ex) { 395 log.error("Validation on [" + wsdlPath + "] failed : " + 396 ex.getMessage(),ex); 397 throw new WebServiceException("Validation on [" + wsdlPath 398 + "] failed : " + ex.getMessage(),ex); 399 } 400 } 401 402 403 409 private Set getOpertations(Parser parser) throws WebServiceException { 410 SymbolTable symbolTable = parser.getSymbolTable(); 411 Map index = symbolTable.getHashMap(); 412 for (Iterator iter = index.keySet().iterator(); iter.hasNext();) { 413 QName key = (QName )iter.next(); 414 Object value = index.get(key); 415 if (value instanceof Vector ) { 416 Vector list = (Vector )value; 417 for (int count = 0; count < list.size(); count++) { 418 Object listValue = list.get(count); 419 if (listValue instanceof BindingEntry) { 420 BindingEntry entry = (BindingEntry)listValue; 421 return entry.getOperations(); 422 } 423 } 424 } 425 } 426 throw new WebServiceException( 427 "There are no operations defined for this wsdl file"); 428 } 429 430 431 437 private MessageContext setupContext() throws WebServiceException { 438 try { 439 AxisServer engine = AxisManager.getInstance().getServer(); 441 MessageContext msgContext = new MessageContext(engine); 442 msgContext.setTransportName(TRANSPORT_NAME); 443 msgContext.setProperty(MessageContext.TRANS_URL, url); 444 msgContext.setProperty(Constants.MC_REALPATH,path); 445 msgContext.setProperty(Constants.MC_RELATIVE_PATH,path); 446 msgContext.setService(service); 447 return msgContext; 448 } catch (Exception ex) { 449 log.error("Failed to setup the message context : " + 450 ex.getMessage(),ex); 451 throw new WebServiceException( 452 "Failed to setup the message context : " + ex.getMessage(), 453 ex); 454 } 455 } 456 457 458 464 private void processException(MessageContext msgContext,Exception ex) throws 465 WebServiceException { 466 try { 467 if (msgContext == null) { 469 throw new WebServiceException("Failed to process request : " + 470 ex.getMessage(),ex); 471 } 472 473 AxisFault af; 475 if (ex instanceof AxisFault) { 476 af = (AxisFault) ex; 477 log.debug(Messages.getMessage("serverFault00"), af); 478 } else { 479 af = AxisFault.makeFault(ex); 480 } 481 482 Message responseMsg = msgContext.getResponseMessage(); 486 if (responseMsg == null) { 487 responseMsg = new Message(af); 488 responseMsg.setMessageContext(msgContext); 489 } else { 490 SOAPEnvelope env = responseMsg.getSOAPEnvelope(); 491 env.clearBody(); 492 env.addBodyElement(new SOAPFault((AxisFault) ex)); 493 } 494 ByteArrayOutputStream output = new ByteArrayOutputStream (); 495 responseMsg.writeTo(output); 496 output.flush(); 497 498 throw new WebServiceException(output.toString(),MimeTypes.XML); 500 } catch (WebServiceException ex2) { 501 throw ex2; 502 } catch (Exception ex2) { 503 log.error("Failed to process the exception : " + 504 ex2.getMessage(),ex2); 505 throw new WebServiceException( 506 "Failed to process the exception : " + ex2.getMessage(), 507 ex2); 508 } 509 } 510 } 511 | Popular Tags |