1 package org.apache.ojb.broker.locking; 2 3 17 18 import java.io.BufferedOutputStream ; 19 import java.io.ByteArrayOutputStream ; 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.ObjectInputStream ; 23 import java.io.ObjectOutputStream ; 24 import java.io.Serializable ; 25 import java.net.HttpURLConnection ; 26 import java.net.MalformedURLException ; 27 import java.net.ProtocolException ; 28 import java.net.URL ; 29 30 import org.apache.ojb.broker.util.configuration.Configurable; 31 import org.apache.ojb.broker.util.configuration.Configuration; 32 import org.apache.ojb.broker.util.configuration.ConfigurationException; 33 import org.apache.ojb.broker.util.logging.Logger; 34 import org.apache.ojb.broker.util.logging.LoggerFactory; 35 36 43 public class LockManagerRemoteImpl implements LockManager, Configurable 44 { 45 private Logger log = LoggerFactory.getLogger(LockManagerRemoteImpl.class); 46 47 public static final byte METHOD_READ_LOCK = 'a'; 48 public static final byte METHOD_WRITE_LOCK = 's'; 49 public static final byte METHOD_UPGRADE_LOCK = 'u'; 50 public static final byte METHOD_CHECK_READ = 'r'; 51 public static final byte METHOD_CHECK_WRITE = 'w'; 52 public static final byte METHOD_CHECK_UPGRADE = 'v'; 53 public static final byte METHOD_RELEASE_SINGLE_LOCK = 'e'; 54 public static final byte METHOD_RELEASE_LOCKS = 'x'; 55 public static final byte METHOD_LOCK_INFO = 'i'; 56 public static final byte METHOD_LOCK_TIMEOUT = 't'; 57 public static final byte METHOD_LOCK_TIMEOUT_SET = 'y'; 58 public static final byte METHOD_BLOCK_TIMEOUT = 'c'; 59 public static final byte METHOD_BLOCK_TIMEOUT_SET = 'd'; 60 61 private static URL lockservlet = null; 62 63 public LockManagerRemoteImpl() 64 { 65 } 66 67 70 public void configure(Configuration pConfig) throws ConfigurationException 71 { 72 String url = pConfig.getString("LockServletUrl", "http://127.0.0.1:8080/ojb-lockserver"); 73 log.info("Lock server servlet URL: " + url); 74 try 75 { 76 lockservlet = new URL (url); 77 } 78 catch(MalformedURLException e) 79 { 80 throw new ConfigurationException("Invalid LockServlet Url was specified: " + url, e); 81 } 82 83 } 84 85 89 public void setLockTimeout(long timeout) 90 { 91 } 102 103 public long getLockTimeout() 104 { 105 LockInfo info = new LockInfo(METHOD_LOCK_TIMEOUT); 106 try 107 { 108 byte[] requestBarr = serialize(info); 109 return performRequestLong(requestBarr); 110 } 111 catch(Throwable t) 112 { 113 throw new LockRuntimeException("Can't get locking info", t); 114 } 115 } 116 117 public long getBlockTimeout() 118 { 119 LockInfo info = new LockInfo(METHOD_BLOCK_TIMEOUT); 120 try 121 { 122 byte[] requestBarr = serialize(info); 123 return performRequestLong(requestBarr); 124 } 125 catch(Throwable t) 126 { 127 throw new LockRuntimeException("Can't get block timeout value", t); 128 } 129 } 130 131 134 public void setBlockTimeout(long timeout) 135 { 136 } 147 148 public String getLockInfo() 149 { 150 LockInfo info = new LockInfo(METHOD_LOCK_INFO); 151 try 152 { 153 byte[] requestBarr = serialize(info); 154 return performRequestString(requestBarr); 155 } 156 catch(Throwable t) 157 { 158 throw new LockRuntimeException("Can't get locking info", t); 159 } 160 } 161 162 public boolean readLock(Object key, Object resourceId, int isolationLevel) 163 { 164 LockInfo info = new LockInfo(key, resourceId, isolationLevel, METHOD_READ_LOCK); 165 try 166 { 167 byte[] requestBarr = serialize(info); 168 return performRequest(requestBarr); 169 } 170 catch(Throwable t) 171 { 172 throw new LockRuntimeException("Cannot check read lock for '" 173 + resourceId + "' using key '" + key + "'", t); 174 } 175 } 176 177 public boolean releaseLock(Object key, Object resourceId) 178 { 179 LockInfo info = new LockInfo(key, resourceId, METHOD_RELEASE_SINGLE_LOCK); 180 try 181 { 182 byte[] requestBarr = serialize(info); 183 return performRequest(requestBarr); 184 } 185 catch(Throwable t) 186 { 187 throw new LockRuntimeException("Cannot remove write lock for '" 188 + resourceId + "' using key '" + key + "'", t); 189 } 190 } 191 192 207 public void releaseLocks(Object key) 208 { 209 LockInfo info = new LockInfo(key, null, METHOD_RELEASE_LOCKS); 210 try 211 { 212 byte[] requestBarr = serialize(info); 213 performRequest(requestBarr); 214 } 215 catch(Throwable t) 216 { 217 throw new LockRuntimeException("Cannot release locks using owner key '" + key + "'", t); 218 } 219 } 220 221 public boolean writeLock(Object key, Object resourceId, int isolationLevel) 222 { 223 LockInfo info = new LockInfo(key, resourceId, isolationLevel, METHOD_WRITE_LOCK); 224 try 225 { 226 byte[] requestBarr = serialize(info); 227 return performRequest(requestBarr); 228 } 229 catch(Throwable t) 230 { 231 throw new LockRuntimeException("Cannot set write lock for '" 232 + resourceId + "' using key '" + key + "'", t); 233 } 234 } 235 236 public boolean upgradeLock(Object key, Object resourceId, int isolationLevel) 237 { 238 LockInfo info = new LockInfo(key, resourceId, isolationLevel, METHOD_UPGRADE_LOCK); 239 try 240 { 241 byte[] requestBarr = serialize(info); 242 return performRequest(requestBarr); 243 } 244 catch(Throwable t) 245 { 246 throw new LockRuntimeException("Cannot set write lock for '" 247 + resourceId + "' using key '" + key + "'", t); 248 } 249 } 250 251 public boolean hasRead(Object key, Object resourceId) 252 { 253 try 254 { 255 byte[] requestBarr = serialize(new LockInfo(key, resourceId, METHOD_CHECK_READ)); 256 return performRequest(requestBarr); 257 } 258 catch(Throwable t) 259 { 260 throw new LockRuntimeException("Cannot check read lock for '" 261 + resourceId + "' using key '" + key + "'", t); 262 } 263 } 264 265 public boolean hasWrite(Object key, Object resourceId) 266 { 267 try 268 { 269 byte[] requestBarr = serialize(new LockInfo(key, resourceId, METHOD_CHECK_WRITE)); 270 return performRequest(requestBarr); 271 } 272 catch(Throwable t) 273 { 274 throw new LockRuntimeException("Cannot check write lock for '" 275 + resourceId + "' using key '" + key + "'", t); 276 } 277 } 278 279 public boolean hasUpgrade(Object key, Object resourceId) 280 { 281 try 282 { 283 byte[] requestBarr = serialize(new LockInfo(key, resourceId, METHOD_CHECK_UPGRADE)); 284 return performRequest(requestBarr); 285 } 286 catch(Throwable t) 287 { 288 throw new LockRuntimeException("Cannot check write lock for '" 289 + resourceId + "' using key '" + key + "'", t); 290 } 291 } 292 293 private HttpURLConnection getHttpUrlConnection() 294 throws MalformedURLException , IOException , ProtocolException 295 { 296 URL lockserver = getLockserverUrl(); 297 HttpURLConnection conn = (HttpURLConnection ) lockserver.openConnection(); 298 299 conn.setDoInput(true); 300 conn.setDoOutput(true); 301 conn.setRequestMethod("POST"); 302 conn.setAllowUserInteraction(false); 303 conn.setUseCaches(false); 304 return conn; 305 } 306 307 private URL getLockserverUrl() 308 { 309 return lockservlet; 310 } 311 312 public byte[] serialize(Object obj) throws IOException 313 { 314 ByteArrayOutputStream bao = new ByteArrayOutputStream (); 315 ObjectOutputStream oos = new ObjectOutputStream (bao); 316 oos.writeObject(obj); 317 oos.close(); 318 bao.close(); 319 byte[] result = bao.toByteArray(); 320 return result; 321 } 322 323 private boolean performRequest(byte[] requestBarr) throws IOException , ClassNotFoundException 324 { 325 Object result = performRequestObject(requestBarr); 326 if(result instanceof Boolean ) 327 { 328 return ((Boolean ) result).booleanValue(); 329 } 330 else 331 { 332 throw new LockRuntimeException("Remote lock server error, expect return value of type 'Boolean'"); 333 } 334 } 335 336 private String performRequestString(byte[] requestBarr) throws IOException , ClassNotFoundException 337 { 338 Object result = performRequestObject(requestBarr); 339 if(result instanceof String ) 340 { 341 return (String ) result; 342 } 343 else 344 { 345 throw new LockRuntimeException("Remote lock server error, expect return value of type 'String'"); 346 } 347 } 348 349 private long performRequestLong(byte[] requestBarr) throws IOException , ClassNotFoundException 350 { 351 Object result = performRequestObject(requestBarr); 352 if(result instanceof Long ) 353 { 354 return ((Long ) result).longValue(); 355 } 356 else 357 { 358 throw new LockRuntimeException("Remote lock server error, expect return value of type 'String'"); 359 } 360 } 361 362 private Object performRequestObject(byte[] requestBarr) throws IOException , ClassNotFoundException 363 { 364 HttpURLConnection conn = getHttpUrlConnection(); 365 366 BufferedOutputStream out = new BufferedOutputStream (conn.getOutputStream()); 368 out.write(requestBarr, 0, requestBarr.length); 369 out.flush(); 370 371 InputStream in = conn.getInputStream(); 373 ObjectInputStream ois = new ObjectInputStream (in); 374 Object result = ois.readObject(); 375 376 ois.close(); 378 out.close(); 379 conn.disconnect(); 380 381 if(result instanceof Throwable ) 382 { 383 throw new LockRuntimeException("Remote lock server error", (Throwable ) result); 384 } 385 else 386 { 387 return result; 388 } 389 } 390 391 public static final class LockInfo implements Serializable 392 { 393 public Object key; 394 public Object resourceId; 395 public int isolationLevel; 396 public byte methodName; 397 public long lockTimeout; 398 public long blockTimeout; 399 400 public LockInfo(byte methodName) 401 { 402 this.methodName = methodName; 403 } 404 405 public LockInfo(Object key, Object resourceId, byte methodName) 406 { 407 this.key = key; 408 this.resourceId = resourceId; 409 this.methodName = methodName; 410 } 411 412 public LockInfo(Object key, Object resourceId, int isolationLevel, byte methodName) 413 { 414 this.key = key; 415 this.resourceId = resourceId; 416 this.isolationLevel = isolationLevel; 417 this.methodName = methodName; 418 } 419 420 } 433 } 434 | Popular Tags |