1 17 package org.apache.servicemix.bpe.external; 18 19 import java.net.URI ; 20 import java.util.HashMap ; 21 import java.util.Iterator ; 22 import java.util.Map ; 23 import java.util.Properties ; 24 25 import javax.jbi.messaging.DeliveryChannel; 26 import javax.jbi.messaging.ExchangeStatus; 27 import javax.jbi.messaging.MessageExchange; 28 import javax.jbi.messaging.MessageExchangeFactory; 29 import javax.jbi.messaging.MessagingException; 30 import javax.jbi.messaging.NormalizedMessage; 31 import javax.wsdl.Definition; 32 import javax.wsdl.Fault; 33 import javax.wsdl.Operation; 34 import javax.wsdl.Part; 35 import javax.wsdl.PortType; 36 import javax.xml.namespace.QName ; 37 import javax.xml.transform.Source ; 38 import javax.xml.transform.dom.DOMSource ; 39 40 import org.apache.commons.logging.Log; 41 import org.apache.commons.logging.LogFactory; 42 import org.apache.ode.bpe.action.external.ActionSystemException; 43 import org.apache.ode.bpe.action.external.IExternalAction; 44 import org.apache.ode.bpe.action.external.IURIResolver; 45 import org.apache.ode.bpe.client.IFormattableValue; 46 import org.apache.ode.bpe.interaction.spiimpl.document.DocumentFormattableValue; 47 import org.apache.ode.bpe.scope.service.BPRuntimeException; 48 import org.apache.servicemix.bpe.BPEComponent; 49 import org.apache.servicemix.bpe.BPEEndpoint; 50 import org.apache.servicemix.bpe.BPELifeCycle; 51 import org.apache.servicemix.bpe.BPEServiceUnit; 52 import org.apache.servicemix.jbi.jaxp.BytesSource; 53 import org.apache.servicemix.jbi.jaxp.SourceTransformer; 54 import org.apache.servicemix.jbi.jaxp.StringSource; 55 import org.w3c.dom.Document ; 56 import org.w3c.dom.Element ; 57 58 public class JbiInvokeAction implements IExternalAction { 59 60 public static final String INTERFACE_NAMESPACE = "interfaceNamespace"; 61 public static final String INTERFACE_LOCALNAME = "interfaceLocalName"; 62 public static final String OPERATION_NAMESPACE = "operationNamespace"; 63 public static final String OPERATION_LOCALNAME = "operationLocalName"; 64 public static final String SERVICE_NAMESPACE = "serviceNamespace"; 65 public static final String SERVICE_LOCALNAME = "serviceLocalName"; 66 public static final String ENDPOINT_NAME = "endpointName"; 67 public static final String ACTION = "action"; 68 public static final String ENDPOINT = "endpoint"; 69 public static final String MEP = "mep"; 70 71 private static Log log = LogFactory.getLog(JbiInvokeAction.class); 72 73 private Properties properties; 74 private QName interfaceName; 75 private QName serviceName; 76 private String endpointName; 77 private QName operationName; 78 private String inputPartName = BPEComponent.PART_PAYLOAD; 79 private String outputPartName = BPEComponent.PART_PAYLOAD; 80 private URI mep; 81 private SourceTransformer transformer; 82 private Operation wsdlOperation; 83 84 87 private static final long serialVersionUID = -8522450752525724302L; 88 89 public JbiInvokeAction() { 90 transformer = new SourceTransformer(); 91 } 92 93 public void init(Properties props) throws BPRuntimeException, ActionSystemException { 94 if (log.isDebugEnabled()) { 95 log.debug("init"); 96 } 97 this.properties = props; 98 extractInformations(); 99 if (serviceName == null && interfaceName == null) { 100 throw new BPRuntimeException("Interface, Service or Endpoint should be specified", ""); 101 } 102 if (log.isDebugEnabled()) { 103 log.debug("properties: " + props); 104 } 105 } 106 107 protected void extractInformations() { 108 String action = properties.getProperty(ACTION); 109 if (action != null) { 110 String [] parts = split(action); 111 interfaceName = new QName (parts[0], parts[1]); 112 operationName = new QName (parts[0], parts[2]); 113 } else { 114 String interfaceNamespace = properties.getProperty(INTERFACE_NAMESPACE); 115 String interfaceLocalName = properties.getProperty(INTERFACE_LOCALNAME); 116 if (interfaceLocalName != null) { 117 interfaceName = new QName (interfaceNamespace, interfaceLocalName); 118 } 119 String operationNamespace = properties.getProperty(OPERATION_NAMESPACE); 120 String operationLocalName = properties.getProperty(OPERATION_LOCALNAME); 121 if (operationLocalName != null) { 122 operationName = new QName (operationNamespace, operationLocalName); 123 } 124 } 125 String endpoint = properties.getProperty(ENDPOINT); 126 if (endpoint != null) { 127 String [] parts = split(action); 128 serviceName = new QName (parts[0], parts[1]); 129 endpointName = parts[2]; 130 } else { 131 String serviceNamespace = properties.getProperty(SERVICE_NAMESPACE); 132 String serviceLocalName = properties.getProperty(SERVICE_LOCALNAME); 133 if (serviceLocalName != null) { 134 serviceName = new QName (serviceNamespace, serviceLocalName); 135 } 136 endpointName = properties.getProperty(ENDPOINT_NAME); 137 } 138 String mep = properties.getProperty(MEP); 139 if (mep == null) { 140 BPEEndpoint ep = BPEEndpoint.getCurrent(); 141 Definition def = ((BPEServiceUnit) ep.getServiceUnit()).getDefinition(); 142 PortType pt = def.getPortType(interfaceName); 143 Operation oper = pt != null ? pt.getOperation(operationName.getLocalPart(), null, null) : null; 144 if (oper != null) { 145 boolean output = oper.getOutput() != null && 146 oper.getOutput().getMessage() != null && 147 oper.getOutput().getMessage().getParts().size() > 0; 148 boolean faults = oper.getFaults().size() > 0; 149 if (output) { 150 mep = "in-out"; 151 } else if (faults) { 152 mep = "robust-in-only"; 153 } else { 154 mep = "in-only"; 155 } 156 if (oper.getInput() != null && oper.getInput().getMessage() != null) { 157 Map parts = oper.getInput().getMessage().getParts(); 158 inputPartName = (String ) parts.keySet().iterator().next(); 159 } 160 if (oper.getOutput() != null && oper.getOutput().getMessage() != null) { 161 Map parts = oper.getOutput().getMessage().getParts(); 162 outputPartName = (String ) parts.keySet().iterator().next(); 163 } 164 wsdlOperation = oper; 165 } 166 } 167 if (mep == null) { 168 mep = "in-out"; 169 } 170 this.mep = URI.create("http://www.w3.org/2004/08/wsdl/" + mep); 171 } 172 173 public void execute(HashMap input, HashMap output, IURIResolver resolver) 174 throws BPRuntimeException, ActionSystemException { 175 if (log.isDebugEnabled()) { 176 log.debug("execute"); 177 } 178 Object payload = input.get(inputPartName); 179 Source inputSource = getSourceFromPayload(payload); 180 try { 182 BPEEndpoint endpoint = BPEEndpoint.getCurrent(); 183 BPEComponent component = (BPEComponent) endpoint.getServiceUnit().getComponent(); 184 DeliveryChannel channel = ((BPELifeCycle) component.getLifeCycle()).getContext().getDeliveryChannel(); 185 MessageExchangeFactory factory = channel.createExchangeFactory(); 186 MessageExchange me = factory.createExchange(this.mep); 188 me.setInterfaceName(interfaceName); 189 me.setService(serviceName); 190 me.setOperation(operationName); 192 NormalizedMessage nm = me.createMessage(); 193 me.setMessage(nm, "in"); 194 nm.setContent(inputSource); 195 boolean res = channel.sendSync(me); 196 if (!res) { 197 throw new ActionSystemException("Timeout on sending message"); 198 } 199 if (me.getStatus() == ExchangeStatus.ACTIVE) { 200 if (me.getFault() != null) { 201 Document fault; 202 try { 203 fault = transformer.toDOMDocument(me.getFault()); 204 me.setStatus(ExchangeStatus.DONE); 205 } catch (Exception e) { 206 me.setError(e); 207 throw new ActionSystemException(e); 208 } finally { 209 channel.send(me); 210 } 211 Element e = fault.getDocumentElement(); 212 String faultName = e.getLocalName(); 214 String partName = BPEComponent.PART_PAYLOAD; 215 QName elemName = new QName (e.getNamespaceURI(), e.getLocalName()); 216 if (wsdlOperation != null) { 217 for (Iterator itFault = wsdlOperation.getFaults().values().iterator(); itFault.hasNext();) { 218 Fault f = (Fault) itFault.next(); 219 Part p = (Part) f.getMessage().getParts().values().iterator().next(); 220 if (elemName.equals(p.getTypeName())) { 221 faultName = f.getName(); 222 partName = p.getName(); 223 } 224 } 225 } 226 BPRuntimeException bpre = new BPRuntimeException(faultName, ""); 227 bpre.setNameSpace(e.getNamespaceURI()); 228 232 DocumentFormattableValue documentFormattableValue = new DocumentFormattableValue(fault); 233 bpre.addPartMessage(partName, documentFormattableValue); 234 throw bpre; 235 } else { 236 try { 237 nm = me.getMessage("out"); 238 if (nm != null) { 239 243 Document out = transformer.toDOMDocument(nm); 244 DocumentFormattableValue documentFormattableValue = new DocumentFormattableValue(out); 245 output.put(outputPartName, documentFormattableValue); 246 } 247 me.setStatus(ExchangeStatus.DONE); 248 } catch (Exception e) { 249 me.setError(e); 250 throw new ActionSystemException(e); 251 } finally { 252 channel.send(me); 253 } 254 } 255 } else if (me.getStatus() == ExchangeStatus.ERROR) { 256 Exception error = me.getError(); 258 throw new BPRuntimeException("Unknown", error); 259 } 260 } catch (MessagingException e) { 261 throw new ActionSystemException(e); 262 } 263 if (log.isDebugEnabled()) { 264 log.debug("Request: " + payload); 265 log.debug("Response: " + output.get(outputPartName)); 266 } 267 } 268 269 protected Source getSourceFromPayload(Object payload) { 270 Source inputSource; 271 if (payload instanceof IFormattableValue) { 272 IFormattableValue value = (IFormattableValue) payload; 273 if (value.supportsGetValueAs(Document .class)) { 274 Document doc = (Document ) value.getValueAs(Document .class); 275 inputSource = new DOMSource (doc); 276 } else if (value.supportsGetValueAs(byte[].class)) { 277 byte[] data = (byte[]) value.getValueAs(byte[].class); 278 inputSource = new BytesSource(data); 279 } else if (value.supportsGetValueAs(String .class)) { 280 String data = (String ) value.getValueAs(String .class); 281 inputSource = new StringSource(data); 282 } else { 283 throw new UnsupportedOperationException ("Unable to retrieve value"); 284 } 285 } else if (payload instanceof Document ) { 286 inputSource = new DOMSource ((Document ) payload); 287 } else if (payload instanceof byte[]) { 288 inputSource = new BytesSource((byte[]) payload); 289 } else if (payload instanceof String ) { 290 inputSource = new StringSource((String ) payload); 291 } else { 292 throw new UnsupportedOperationException ("Unable to retrieve value"); 293 } 294 return inputSource; 295 } 296 297 public void release() { 298 if (log.isDebugEnabled()) { 299 log.debug("release"); 300 } 301 } 302 303 public void process(MessageExchange exchange) throws Exception { 304 306 } 307 308 public void start() throws Exception { 309 311 } 312 313 public void stop() throws Exception { 314 316 } 317 318 protected String [] split(String uri) { 319 char sep; 320 if (uri.indexOf('/') > 0) { 321 sep = '/'; 322 } else { 323 sep = ':'; 324 } 325 int idx1 = uri.lastIndexOf(sep); 326 int idx2 = uri.lastIndexOf(sep, idx1 - 1); 327 String epName = uri.substring(idx1 + 1); 328 String svcName = uri.substring(idx2 + 1, idx1); 329 String nsUri = uri.substring(0, idx2); 330 return new String [] { nsUri, svcName, epName }; 331 } 332 } 333 | Popular Tags |