1 22 package org.jboss.ejb.plugins.inflow; 23 24 import java.lang.reflect.Method ; 25 import java.util.ArrayList ; 26 import java.util.Collection ; 27 import java.util.HashMap ; 28 import java.util.Iterator ; 29 30 import javax.ejb.EJBMetaData ; 31 import javax.management.ObjectName ; 32 import javax.resource.spi.ActivationSpec ; 33 import javax.resource.spi.UnavailableException ; 34 import javax.resource.spi.endpoint.MessageEndpoint ; 35 import javax.resource.spi.endpoint.MessageEndpointFactory ; 36 import javax.transaction.xa.XAResource ; 37 38 import org.jboss.deployment.DeploymentException; 39 import org.jboss.ejb.Container; 40 import org.jboss.ejb.EJBProxyFactory; 41 import org.jboss.ejb.MessageDrivenContainer; 42 import org.jboss.invocation.Invocation; 43 import org.jboss.invocation.InvocationType; 44 import org.jboss.invocation.InvokerInterceptor; 45 import org.jboss.metadata.ActivationConfigPropertyMetaData; 46 import org.jboss.metadata.InvokerProxyBindingMetaData; 47 import org.jboss.metadata.MessageDestinationMetaData; 48 import org.jboss.metadata.MessageDrivenMetaData; 49 import org.jboss.metadata.MetaData; 50 import org.jboss.mx.util.JMXExceptionDecoder; 51 import org.jboss.proxy.GenericProxyFactory; 52 import org.jboss.system.ServiceMBeanSupport; 53 import org.w3c.dom.Element ; 54 import org.w3c.dom.Node ; 55 import org.w3c.dom.NodeList ; 56 57 import EDU.oswego.cs.dl.util.concurrent.SynchronizedInt; 58 59 67 public class JBossMessageEndpointFactory 68 extends ServiceMBeanSupport 69 implements EJBProxyFactory, MessageEndpointFactory , JBossMessageEndpointFactoryMBean 70 { 71 73 75 76 protected boolean trace = log.isTraceEnabled(); 77 78 79 protected MessageDrivenContainer container; 80 81 82 protected MessageDrivenMetaData metaData; 83 84 85 protected String invokerBinding; 86 87 88 protected InvokerProxyBindingMetaData invokerMetaData; 89 90 91 protected HashMap properties = new HashMap (); 92 93 94 protected GenericProxyFactory proxyFactory = new GenericProxyFactory(); 95 96 97 protected Class messagingTypeClass; 98 99 100 protected String resourceAdapterName; 101 102 103 protected ObjectName resourceAdapterObjectName; 104 105 106 protected ActivationSpec activationSpec; 107 108 109 protected ArrayList interceptors; 110 111 112 protected Class [] interfaces; 113 114 115 protected SynchronizedInt nextProxyId = new SynchronizedInt(0); 116 117 119 120 protected String [] createActivationSpecSig = new String [] 121 { 122 Class .class.getName(), 123 Collection .class.getName() 124 }; 125 126 127 protected String [] activationSig = new String [] 128 { 129 MessageEndpointFactory .class.getName(), 130 ActivationSpec .class.getName() 131 }; 132 133 135 137 142 public MessageDrivenContainer getContainer() 143 { 144 return container; 145 } 146 147 154 public String getConfig() 155 { 156 return toString(); 157 } 158 159 161 public MessageEndpoint createEndpoint(XAResource resource) throws UnavailableException 162 { 163 trace = log.isTraceEnabled(); 164 165 if (getState() != STARTED && getState() != STARTING) 166 throw new UnavailableException ("The container is not started"); 167 168 HashMap context = new HashMap (); 169 context.put(MessageEndpointInterceptor.MESSAGE_ENDPOINT_FACTORY, this); 170 context.put(MessageEndpointInterceptor.MESSAGE_ENDPOINT_XARESOURCE, resource); 171 172 String ejbName = container.getBeanMetaData().getContainerObjectNameJndiName(); 173 174 if (trace) 175 log.trace("createEndpoint " + this + " xaResource=" + resource); 176 177 MessageEndpoint endpoint = (MessageEndpoint ) proxyFactory.createProxy 178 ( 179 ejbName + "@" + nextProxyId.increment(), 180 container.getServiceName(), 181 InvokerInterceptor.getLocal(), 182 null, 183 null, 184 interceptors, 185 container.getClassLoader(), 186 interfaces, 187 context 188 ); 189 190 if (trace) 191 log.trace("Created endpoint " + endpoint + " from " + this); 192 193 return endpoint; 194 } 195 196 public boolean isDeliveryTransacted(Method method) throws NoSuchMethodException 197 { 198 boolean result = false; 199 int transType = metaData.getMethodTransactionType(method.getName(), method.getParameterTypes(), InvocationType.LOCAL); 200 if (transType == MetaData.TX_REQUIRED) 201 result = true; 202 if (trace) 203 log.trace("isDeliveryTransacted " + container.getBeanMetaData().getContainerObjectNameJndiName() + " method=" + method + " result=" + result); 204 return result; 205 } 206 207 209 protected void startService() throws Exception 210 { 211 metaData = (MessageDrivenMetaData) container.getBeanMetaData(); 213 resolveMessageListener(); 215 resolveResourceAdapter(); 217 createActivationSpec(); 219 setupProxyParameters(); 221 activate(); 223 } 224 225 protected void stopService() throws Exception 226 { 227 deactivate(); 229 } 230 231 233 public boolean isIdentical(Container container, Invocation mi) 234 { 235 throw new Error ("Not valid for MessageDriven beans"); 236 } 237 238 public Object getEJBHome() 239 { 240 throw new Error ("Not valid for MessageDriven beans"); 241 } 242 243 public EJBMetaData getEJBMetaData() 244 { 245 throw new Error ("Not valid for MessageDriven beans"); 246 } 247 248 public Collection getEntityCollection(Collection c) 249 { 250 throw new Error ("Not valid for MessageDriven beans"); 251 } 252 253 public Object getEntityEJBObject(Object id) 254 { 255 throw new Error ("Not valid for MessageDriven beans"); 256 } 257 258 public Object getStatefulSessionEJBObject(Object id) 259 { 260 throw new Error ("Not valid for MessageDriven beans"); 261 } 262 263 public Object getStatelessSessionEJBObject() 264 { 265 throw new Error ("Not valid for MessageDriven beans"); 266 } 267 268 public void setInvokerBinding(String binding) 269 { 270 this.invokerBinding = binding; 271 } 272 273 public void setInvokerMetaData(InvokerProxyBindingMetaData imd) 274 { 275 this.invokerMetaData = imd; 276 } 277 278 280 285 public void setContainer(final Container container) 286 { 287 this.container = (MessageDrivenContainer) container; 288 } 289 290 292 295 public String toString() 296 { 297 StringBuffer buffer = new StringBuffer (100); 298 buffer.append(super.toString()); 299 buffer.append("{ resourceAdapter=").append(resourceAdapterObjectName); 300 buffer.append(", messagingType=").append(messagingTypeClass.getName()); 301 buffer.append(", ejbName=").append(container.getBeanMetaData().getContainerObjectNameJndiName()); 302 buffer.append(", activationConfig=").append(properties.values()); 303 buffer.append(", activationSpec=").append(activationSpec); 304 buffer.append("}"); 305 return buffer.toString(); 306 } 307 308 310 315 protected void resolveMessageListener() throws DeploymentException 316 { 317 String messagingType = metaData.getMessagingType(); 318 try 319 { 320 messagingTypeClass = GetTCLAction.getContextClassLoader().loadClass(messagingType); 321 } 322 catch (Exception e) 323 { 324 DeploymentException.rethrowAsDeploymentException("Could not load messaging-type class " + messagingType, e); 325 } 326 } 327 328 334 protected String resolveResourceAdapterName() throws DeploymentException 335 { 336 return metaData.getResourceAdapterName(); 337 } 338 339 344 protected void resolveResourceAdapter() throws DeploymentException 345 { 346 resourceAdapterName = resolveResourceAdapterName(); 347 try 348 { 349 resourceAdapterObjectName = new ObjectName ("jboss.jca:service=RARDeployment,name='" + resourceAdapterName + "'"); 350 int state = ((Integer ) server.getAttribute(resourceAdapterObjectName, "State")).intValue(); 351 if (state != STARTED) 352 throw new DeploymentException("The resource adapter is not started " + resourceAdapterName); 353 } 354 catch (Exception e) 355 { 356 DeploymentException.rethrowAsDeploymentException("Cannot locate resource adapter deployment " + resourceAdapterName, e); 357 } 358 } 359 360 365 protected void setupProxyParameters() throws DeploymentException 366 { 367 interfaces = new Class [] { MessageEndpoint .class, messagingTypeClass }; 369 370 interceptors = new ArrayList (); 372 Element proxyConfig = invokerMetaData.getProxyFactoryConfig(); 373 Element endpointInterceptors = MetaData.getOptionalChild(proxyConfig, "endpoint-interceptors", null); 374 if (endpointInterceptors == null) 375 throw new DeploymentException("No endpoint interceptors found"); 376 else 377 { 378 NodeList children = endpointInterceptors.getElementsByTagName("interceptor"); 379 for (int i = 0; i < children.getLength(); ++i) 380 { 381 Node currentChild = children.item(i); 382 if (currentChild.getNodeType() == Node.ELEMENT_NODE) 383 { 384 Element interceptor = (Element ) children.item(i); 385 String className = MetaData.getElementContent(interceptor); 386 try 387 { 388 Class clazz = container.getClassLoader().loadClass(className); 389 interceptors.add(clazz); 390 } 391 catch (Throwable t) 392 { 393 DeploymentException.rethrowAsDeploymentException("Error loading interceptor class " + className, t); 394 } 395 } 396 } 397 } 398 } 399 400 405 protected void augmentActivationConfigProperties() throws DeploymentException 406 { 407 Element proxyConfig = invokerMetaData.getProxyFactoryConfig(); 409 Element activationConfig = MetaData.getOptionalChild(proxyConfig, "activation-config"); 410 if (activationConfig != null) 411 { 412 Iterator iterator = MetaData.getChildrenByTagName(activationConfig, "activation-config-property"); 413 while (iterator.hasNext()) 414 { 415 Element resourceRef = (Element ) iterator.next(); 416 ActivationConfigPropertyMetaData metaData = new ActivationConfigPropertyMetaData(); 417 metaData.importXml(resourceRef); 418 if (properties.containsKey(metaData.getName()) == false) 419 properties.put(metaData.getName(), metaData); 420 } 421 } 422 423 String link = metaData.getDestinationLink(); 425 if (link != null) 426 { 427 link = link.trim(); 428 if (link.length() > 0) 429 { 430 if (properties.containsKey("destination")) 431 log.warn("Ignoring message-destination-link '" + link + "' when the destination " + 432 "is already in the activation-config."); 433 else 434 { 435 MessageDestinationMetaData destinationMetaData = container.getMessageDestination(link); 436 if (destinationMetaData == null) 437 throw new DeploymentException("Unresolved message-destination-link '" + link + "' no message-destination in ejb-jar.xml"); 438 String jndiName = destinationMetaData.getJNDIName(); 439 if (jndiName == null) 440 throw new DeploymentException("The message-destination '" + link + "' has no jndi-name in jboss.xml"); 441 properties.put("destination", jndiName); 442 } 443 } 444 } 445 } 446 447 452 protected void createActivationSpec() throws DeploymentException 453 { 454 properties = new HashMap (metaData.getActivationConfigProperties()); 455 augmentActivationConfigProperties(); 456 457 Object [] params = new Object [] 458 { 459 messagingTypeClass, 460 properties.values() 461 }; 462 try 463 { 464 activationSpec = (ActivationSpec ) server.invoke(resourceAdapterObjectName, "createActivationSpec", params, createActivationSpecSig); 465 } 466 catch (Throwable t) 467 { 468 t = JMXExceptionDecoder.decode(t); 469 DeploymentException.rethrowAsDeploymentException("Unable to create activation spec ra=" + resourceAdapterObjectName + 470 " messaging-type=" + messagingTypeClass.getName() + " properties=" + metaData.getActivationConfigProperties(), t); 471 } 472 } 473 474 479 protected void activate() throws DeploymentException 480 { 481 Object [] params = new Object [] { this, activationSpec }; 482 try 483 { 484 server.invoke(resourceAdapterObjectName, "endpointActivation", params, activationSig); 485 } 486 catch (Throwable t) 487 { 488 t = JMXExceptionDecoder.decode(t); 489 DeploymentException.rethrowAsDeploymentException("Endpoint activation failed ra=" + resourceAdapterObjectName + 490 " activationSpec=" + activationSpec, t); 491 } 492 } 493 494 497 protected void deactivate() 498 { 499 Object [] params = new Object [] { this, activationSpec }; 500 try 501 { 502 server.invoke(resourceAdapterObjectName, "endpointDeactivation", params, activationSig); 503 } 504 catch (Throwable t) 505 { 506 t = JMXExceptionDecoder.decode(t); 507 log.warn("Endpoint activation failed ra=" + resourceAdapterObjectName + 508 " activationSpec=" + activationSpec, t); 509 } 510 } 511 512 514 516 } 518 | Popular Tags |