1 22 package org.jboss.jms.recovery; 23 24 import javax.jms.ExceptionListener ; 25 import javax.jms.JMSException ; 26 import javax.jms.XAConnection ; 27 import javax.jms.XAConnectionFactory ; 28 import javax.jms.XASession ; 29 import javax.naming.Context ; 30 import javax.naming.InitialContext ; 31 import javax.transaction.xa.XAException ; 32 import javax.transaction.xa.XAResource ; 33 import javax.transaction.xa.Xid ; 34 35 import org.jboss.jms.jndi.JMSProviderAdapter; 36 import org.jboss.logging.Logger; 37 import org.jboss.util.naming.Util; 38 39 45 public class XAResourceWrapper implements XAResource , ExceptionListener 46 { 47 48 private static final Logger log = Logger.getLogger(XAResourceWrapper.class); 49 50 51 private String providerName; 52 53 54 private static final Object lock = new Object (); 55 56 57 private XAConnection connection; 58 59 60 private XAResource delegate; 61 62 67 public String getProviderName() 68 { 69 return providerName; 70 } 71 72 77 public void setProviderName(String providerName) 78 { 79 this.providerName = providerName; 80 } 81 82 public Xid [] recover(int flag) throws XAException 83 { 84 log.debug("Recover " + providerName); 85 XAResource xaResource = getDelegate(); 86 try 87 { 88 return xaResource.recover(flag); 89 } 90 catch (XAException e) 91 { 92 throw check(e); 93 } 94 } 95 96 public void commit(Xid xid, boolean onePhase) throws XAException 97 { 98 log.debug("Commit " + providerName + " xid " + " onePhase=" + onePhase); 99 XAResource xaResource = getDelegate(); 100 try 101 { 102 xaResource.commit(xid, onePhase); 103 } 104 catch (XAException e) 105 { 106 throw check(e); 107 } 108 } 109 110 public void rollback(Xid xid) throws XAException 111 { 112 log.debug("Rollback " + providerName + " xid "); 113 XAResource xaResource = getDelegate(); 114 try 115 { 116 xaResource.rollback(xid); 117 } 118 catch (XAException e) 119 { 120 throw check(e); 121 } 122 } 123 124 public void forget(Xid xid) throws XAException 125 { 126 log.debug("Forget " + providerName + " xid "); 127 XAResource xaResource = getDelegate(); 128 try 129 { 130 xaResource.forget(xid); 131 } 132 catch (XAException e) 133 { 134 throw check(e); 135 } 136 } 137 138 public boolean isSameRM(XAResource xaRes) throws XAException 139 { 140 if (xaRes instanceof XAResourceWrapper) 141 xaRes = ((XAResourceWrapper) xaRes).getDelegate(); 142 143 XAResource xaResource = getDelegate(); 144 try 145 { 146 return xaResource.isSameRM(xaRes); 147 } 148 catch (XAException e) 149 { 150 throw check(e); 151 } 152 } 153 154 public int prepare(Xid xid) throws XAException 155 { 156 XAResource xaResource = getDelegate(); 157 try 158 { 159 return xaResource.prepare(xid); 160 } 161 catch (XAException e) 162 { 163 throw check(e); 164 } 165 } 166 167 public void start(Xid xid, int flags) throws XAException 168 { 169 XAResource xaResource = getDelegate(); 170 try 171 { 172 xaResource.start(xid, flags); 173 } 174 catch (XAException e) 175 { 176 throw check(e); 177 } 178 } 179 180 public void end(Xid xid, int flags) throws XAException 181 { 182 XAResource xaResource = getDelegate(); 183 try 184 { 185 xaResource.end(xid, flags); 186 } 187 catch (XAException e) 188 { 189 throw check(e); 190 } 191 } 192 193 public int getTransactionTimeout() throws XAException 194 { 195 XAResource xaResource = getDelegate(); 196 try 197 { 198 return xaResource.getTransactionTimeout(); 199 } 200 catch (XAException e) 201 { 202 throw check(e); 203 } 204 } 205 206 public boolean setTransactionTimeout(int seconds) throws XAException 207 { 208 XAResource xaResource = getDelegate(); 209 try 210 { 211 return xaResource.setTransactionTimeout(seconds); 212 } 213 catch (XAException e) 214 { 215 throw check(e); 216 } 217 } 218 219 public void onException(JMSException exception) 220 { 221 log.warn("Notified of connection failure in recovery delegate for provider " + providerName, exception); 222 close(); 223 } 224 225 231 public XAResource getDelegate() throws XAException 232 { 233 XAResource result = null; 234 Exception error = null; 235 try 236 { 237 result = connect(); 238 } 239 catch (Exception e) 240 { 241 error = e; 242 } 243 244 if (result == null) 245 { 246 XAException xae = new XAException ("Error trying to connect to provider " + providerName); 247 xae.errorCode = XAException.XAER_RMERR; 248 if (error != null) 249 xae.initCause(error); 250 log.debug("Cannot get delegate XAResource", xae); 251 throw xae; 252 } 253 254 return result; 255 } 256 257 263 protected XAResource connect() throws Exception 264 { 265 synchronized (lock) 267 { 268 if (delegate != null) 269 return delegate; 270 } 271 272 XAConnection xaConnection = getConnectionFactory().createXAConnection(); 274 synchronized (lock) 275 { 276 connection = xaConnection; 277 } 278 279 try 281 { 282 XASession session = connection.createXASession(); 283 XAResource result = session.getXAResource(); 284 synchronized (lock) 285 { 286 delegate = result; 287 } 288 return delegate; 289 } 290 catch (Exception e) 291 { 292 close(); 293 throw e; 294 } 295 } 296 297 303 protected XAConnectionFactory getConnectionFactory() throws Exception 304 { 305 if (providerName == null) 307 throw new IllegalArgumentException ("Null provider name"); 308 String providerAdapterJNDI = providerName; 309 if (providerAdapterJNDI.startsWith("java:") == false) 310 providerAdapterJNDI = "java:" + providerAdapterJNDI; 311 Context ctx = new InitialContext (); 312 JMSProviderAdapter adapter = (JMSProviderAdapter) Util.lookup(providerAdapterJNDI, JMSProviderAdapter.class); 313 314 String connectionFactoryRef = adapter.getFactoryRef(); 316 if (connectionFactoryRef == null) 317 throw new IllegalStateException ("Provider '" + providerName + "' has no FactoryRef"); 318 319 ctx = adapter.getInitialContext(); 321 try 322 { 323 return (XAConnectionFactory ) Util.lookup(ctx, connectionFactoryRef, XAConnectionFactory .class); 324 } 325 finally 326 { 327 ctx.close(); 328 } 329 } 330 331 334 public void close() 335 { 336 try 337 { 338 XAConnection oldConnection = null; 339 synchronized (lock) 340 { 341 oldConnection = connection; 342 connection = null; 343 delegate = null; 344 } 345 if (oldConnection != null) 346 oldConnection.close(); 347 } 348 catch (Exception ignored) 349 { 350 log.trace("Ignored error during close", ignored); 351 } 352 } 353 354 362 protected XAException check(XAException e) throws XAException 363 { 364 if (e.errorCode == XAException.XAER_RMERR || e.errorCode == XAException.XAER_RMFAIL) 365 { 366 log.debug("Fatal error in provider " + providerName, e); 367 close(); 368 } 369 throw e; 370 } 371 372 protected void finalize() throws Throwable 373 { 374 close(); 375 } 376 } 377 | Popular Tags |