1 22 package org.objectweb.petals.engine.forward; 23 24 import java.net.URI ; 25 import java.util.HashMap ; 26 import java.util.Iterator ; 27 import java.util.Map ; 28 import java.util.Properties ; 29 import java.util.Set ; 30 import java.util.logging.Level ; 31 import java.util.logging.Logger ; 32 33 import javax.activation.DataHandler ; 34 import javax.jbi.JBIException; 35 import javax.jbi.management.DeploymentException; 36 import javax.jbi.messaging.DeliveryChannel; 37 import javax.jbi.messaging.ExchangeStatus; 38 import javax.jbi.messaging.Fault; 39 import javax.jbi.messaging.InOnly; 40 import javax.jbi.messaging.InOptionalOut; 41 import javax.jbi.messaging.InOut; 42 import javax.jbi.messaging.MessageExchange; 43 import javax.jbi.messaging.MessageExchangeFactory; 44 import javax.jbi.messaging.MessagingException; 45 import javax.jbi.messaging.NormalizedMessage; 46 import javax.jbi.messaging.RobustInOnly; 47 import javax.jbi.servicedesc.ServiceEndpoint; 48 import javax.xml.namespace.QName ; 49 import javax.xml.transform.Source ; 50 import javax.xml.transform.TransformerException ; 51 52 import org.objectweb.petals.component.common.basic.AbstractComponent; 53 import org.objectweb.petals.component.common.basic.AbstractServiceUnitManager; 54 import org.objectweb.petals.component.common.util.SourceHelper; 55 import org.objectweb.petals.component.common.util.XMLHelper; 56 import org.w3c.dom.DOMException ; 57 import org.w3c.dom.Node ; 58 import org.w3c.dom.NodeList ; 59 import org.w3c.dom.Text ; 60 61 62 93 public class Forward extends AbstractComponent { 94 95 public static final String INONLY_METHOD = "InOnly"; 96 public static final String INOUT_METHOD = "InOut"; 97 public static final String INOPTIONALOUT_METHOD = "InOptionalOut"; 98 public static final String ROBUSTINONLY_METHOD = "RobustInOnly"; 99 100 101 private Map <QName , Properties > serviceToPropertiesMap = new HashMap <QName , Properties >(); 102 103 104 108 public Forward() { 109 super(); 110 } 111 112 116 public Forward(DeliveryChannel channel, Logger log) { 117 super(channel, log); 118 } 119 120 121 @Override 122 protected boolean handleMessage(QName service, QName operation, 123 NormalizedMessage in, NormalizedMessage out, URI messageExhangePattern) 124 throws Exception { 125 Properties props = getServiceProperties(service); 127 128 NormalizedMessage currentIn = in; 129 NormalizedMessage currentOut = null; 130 for (int i = 0; ; i++) { 131 String targetServiceNameProp = "service_" + i; 133 String targetServiceOperationProp = "operation_" + i; 134 String targetServiceMethodProp = "method_" + i; 135 String targetServiceName = props.getProperty(targetServiceNameProp); 136 String targetServiceOperation = props.getProperty(targetServiceOperationProp, ""); 137 String targetServiceMethod = props.getProperty(targetServiceMethodProp, INOUT_METHOD); 138 if (targetServiceName == null || targetServiceName.length() == 0) { 139 break; 141 } 142 143 QName targetService = QName.valueOf(targetServiceName); 145 ServiceEndpoint[] targetEndpoints = this.getComponentContext() 146 .getEndpointsForService(targetService); 147 if (targetEndpoints == null || targetEndpoints.length == 0) { 148 throw new Exception ("No endpoint found for service " 149 + targetServiceName); 150 } 151 152 if (currentIn == null) { 153 throw new Exception ("Previous forward had no OUT message " 154 + "so there can't be another forward afterwards to " 155 + targetServiceName + "." + targetServiceOperation); 156 } 157 158 try { 159 currentOut = forwardCopy(currentIn, 160 targetService, targetServiceOperation, targetServiceMethod); 161 } catch (Exception e) { 162 throw new Exception ("Error when forwarding to service and operation " 163 + targetServiceName + "." + targetServiceOperation, e); 164 } 165 if (currentOut == null) { 166 continue; 170 171 } else if (currentOut instanceof Fault) { 172 String faultString = SourceHelper.createString(currentOut.getContent()); 173 throw new Exception ("Service fault received from call " 174 + "to service and operation " + targetServiceName 175 + "." + targetServiceOperation + " : " + faultString); 176 } 177 178 currentIn = currentOut; 180 } 181 182 if (out != null) { 183 if (currentOut == null) { 184 out.setContent(SourceHelper.createSource("<success/>")); 186 } else { 187 copy(currentOut, out); 189 } 190 } return true; 192 } 193 194 195 201 protected final static void copy(NormalizedMessage originalNm, 202 NormalizedMessage copyNm) throws Exception { 203 String contentString = SourceHelper.createString(originalNm.getContent()); 205 copyNm.setContent(SourceHelper.createSource(contentString)); 206 207 Set inAttachmentNameSet = originalNm.getAttachmentNames(); 209 if (inAttachmentNameSet != null) { 210 for (Iterator nameIt = inAttachmentNameSet.iterator(); nameIt.hasNext();) { 211 String attachmentName = (String ) nameIt.next(); 212 DataHandler attDh = originalNm.getAttachment(attachmentName); 213 try { 214 copyNm.addAttachment(attachmentName, attDh); 215 } catch (MessagingException e) { 216 throw new Exception ("Error when attaching file " 217 + attachmentName, e); 218 } 219 } 220 } 221 } 222 223 224 234 protected NormalizedMessage forwardCopy(NormalizedMessage originalIn, 235 QName service, String operation, String method) throws Exception { 236 MessageExchangeFactory mef = this.getDeliveryChannel().createExchangeFactory(); 238 MessageExchange msg; 239 if (INONLY_METHOD.equals(method)) { 240 msg = mef.createInOnlyExchange(); 241 } else if (INOUT_METHOD.equals(method)) { 242 msg = mef.createInOutExchange(); 243 } else if (INOPTIONALOUT_METHOD.equals(method)) { 244 msg = mef.createInOptionalOutExchange(); 245 } else if (ROBUSTINONLY_METHOD.equals(method)) { 246 msg = mef.createRobustInOnlyExchange(); 247 } else { 248 throw new Exception ("Unknown method " + method); 249 } 250 251 msg.setService(service); 253 msg.setOperation(QName.valueOf(operation)); 254 255 NormalizedMessage copyIn = msg.createMessage(); 257 copy(originalIn, copyIn); 258 if (INONLY_METHOD.equals(method)) { 259 ((InOnly) msg).setInMessage(copyIn); 260 } else if (INOUT_METHOD.equals(method)) { 261 ((InOut) msg).setInMessage(copyIn); 262 } else if (INOPTIONALOUT_METHOD.equals(method)) { 263 ((InOptionalOut) msg).setInMessage(copyIn); 264 } else if (ROBUSTINONLY_METHOD.equals(method)) { 265 ((RobustInOnly) msg).setInMessage(copyIn); 266 } else { 267 throw new Exception ("Unknown method " + method); 268 } 269 270 boolean ok = this.getDeliveryChannel().sendSync(msg, 0); 272 if(ok) { 273 if (ExchangeStatus.DONE.equals(msg.getStatus())) { 274 return null; 276 } else if (ExchangeStatus.ERROR.equals(msg.getStatus())) { 277 String err = "ERROR status ! "; 278 log.log(Level.SEVERE, err, msg.getError()); 279 throw new Exception (err, msg.getError()); 281 } else { 282 try { 283 NormalizedMessage out = null; 284 if (msg.getMessage("OUT") != null) { 286 out = msg.getMessage("OUT"); 287 } else if (msg.getFault() != null) { 288 out = msg.getFault(); 289 } else { 290 } 292 NormalizedMessage copyOut = msg.createMessage(); 293 copy(out, copyOut); 294 295 msg.setStatus(ExchangeStatus.DONE); 296 this.getDeliveryChannel().send(msg); 297 return out; 298 299 } catch (Exception e) { 300 String err = "Error while getting response message"; 301 log.log(Level.SEVERE, err, e); 302 throw new Exception (err, e); } 304 } 305 } else { 306 String err = "Timeout !"; 307 log.log(Level.SEVERE, err); 308 throw new Exception (err); } 310 } 311 312 313 314 325 protected String transformToContentString(Source contentSource) throws ContentException { 326 try { 327 Node contentDocumentNode = XMLHelper.createDOMNodeFromSource(contentSource); 328 Node contentNode = XMLHelper.getFirstChild(contentDocumentNode); 329 NodeList queryNodes = contentNode.getChildNodes(); 331 int queryNodeNb = queryNodes.getLength(); 332 if (queryNodeNb == 1) { 333 Node singleQueryNode = queryNodes.item(0); 334 if (singleQueryNode instanceof Text ) { 335 return ((Text ) singleQueryNode).getTextContent(); 336 } 337 } 338 StringBuffer contentBuf = new StringBuffer (); 339 for (int i = 0; i < queryNodeNb ; i++) { 340 Node queryNode = queryNodes.item(i); 341 contentBuf.append(XMLHelper.createStringFromDOMNode(queryNode)); 344 contentBuf.append("\n"); 345 } 346 return contentBuf.toString(); 347 348 } catch (DOMException e) { 349 String msg = "Error while reading content string from XML Source " 350 + tryToCreateStringForError(contentSource); 351 log.log(Level.SEVERE, msg, e); 352 throw new ContentException(msg, e); 353 } catch (TransformerException e) { 354 String msg = "Error while reading content string from XML Source " 355 + tryToCreateStringForError(contentSource); 356 log.log(Level.SEVERE, msg, e); 357 throw new ContentException(msg, e); 358 } 359 } 360 361 374 protected String transformToContentStringWithRootTag( 375 Source contentSource, String contentTag) throws ContentException { 376 try { 377 Node contentDocumentNode = XMLHelper.createDOMNodeFromSource(contentSource); 378 Node contentNode = XMLHelper.getFirstChild(contentDocumentNode); 379 if (!contentTag.equals(contentNode.getLocalName())) { 381 throw new ContentException("Such messages should be " 382 + "encapsulated in a top <\"" + contentTag + "\"> tag !"); 383 } 384 NodeList queryNodes = contentNode.getChildNodes(); 386 int queryNodeNb = queryNodes.getLength(); 387 if (queryNodeNb == 1) { 388 Node singleQueryNode = queryNodes.item(0); 389 if (singleQueryNode instanceof Text ) { 390 return ((Text ) singleQueryNode).getTextContent(); 391 } 392 } 393 StringBuffer contentBuf = new StringBuffer (); 394 for (int i = 0; i < queryNodeNb ; i++) { 395 Node queryNode = queryNodes.item(i); 396 contentBuf.append(XMLHelper.createStringFromDOMNode(queryNode)); 399 contentBuf.append("\n"); 400 } 401 return contentBuf.toString(); 402 403 } catch (DOMException e) { 404 String msg = "Error while reading content string from XML Source " 405 + tryToCreateStringForError(contentSource); 406 log.log(Level.SEVERE, msg, e); 407 throw new ContentException(msg, e); 408 } catch (TransformerException e) { 409 String msg = "Error while reading content string from XML Source " 410 + tryToCreateStringForError(contentSource); 411 log.log(Level.SEVERE, msg, e); 412 throw new ContentException(msg, e); 413 } 414 } 415 416 417 424 protected Node transformToContentNode(Source contentSource) throws ContentException { 425 try { 426 Node contentDocumentNode = XMLHelper.createDOMNodeFromSource(contentSource); 427 Node contentNode = XMLHelper.getFirstChild(contentDocumentNode); 428 return contentNode; 429 } catch (TransformerException e) { 430 String msg = "Error while reading content node from XML Source " 431 + tryToCreateStringForError(contentSource); 432 log.log(Level.SEVERE, msg, e); 433 throw new ContentException(msg, e); 434 } 435 } 436 437 446 protected Node transformToContentNodeWithRootTag( 447 Source contentSource, String contentTag) throws ContentException { 448 try { 449 Node contentDocumentNode = XMLHelper.createDOMNodeFromSource(contentSource); 450 Node contentNode = XMLHelper.getFirstChild(contentDocumentNode); 451 if (!contentTag.equals(contentNode.getLocalName())) { 453 throw new ContentException("Such messages should be " 454 + "encapsulated in a top <\"" + contentTag + "\"> tag !"); 455 } 456 return contentNode; 457 } catch (TransformerException e) { 458 String msg = "Error while reading content node from XML Source " 459 + tryToCreateStringForError(contentSource); 460 log.log(Level.SEVERE, msg, e); 461 throw new ContentException(msg, e); 462 } 463 } 464 465 466 public static final String tryToCreateStringForError(Source contentSource) { 467 String contentString; 468 try { 469 contentString = SourceHelper.createString(contentSource); 471 } catch (Exception e) { 472 contentString = "[[error in transforming Source to String]]"; 474 } 475 return contentString; 476 } 477 478 479 485 protected Properties getServiceProperties(QName service) throws Exception { 486 Properties csvProperties = this.serviceToPropertiesMap.get(service); 487 if (csvProperties != null) { 488 return csvProperties; 489 } else { 490 throw new Exception ("Service properties not found for service " 491 + service); 492 } 493 } 494 495 496 @Override 497 protected AbstractServiceUnitManager createServiceUnitManager() throws DeploymentException { 498 PropertiesServiceUnitManager suMgr; 500 try { 501 suMgr = new PropertiesServiceUnitManager(this.getComponentContext(), 502 log, serviceToPropertiesMap); 503 } catch (JBIException e) { 504 throw new DeploymentException("Unable to get component context", e); 505 } 506 return suMgr; 507 } 508 509 } 510 | Popular Tags |