Coverage Report - org.apache.ojb.odmg.locking.RemoteLockMapImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
RemoteLockMapImpl
N/A
N/A
2.19
 
 1  
 package org.apache.ojb.odmg.locking;
 2  
 
 3  
 /* Copyright 2004-2005 The Apache Software Foundation
 4  
  *
 5  
  * Licensed under the Apache License, Version 2.0 (the "License");
 6  
  * you may not use this file except in compliance with the License.
 7  
  * You may obtain a copy of the License at
 8  
  *
 9  
  *     http://www.apache.org/licenses/LICENSE-2.0
 10  
  *
 11  
  * Unless required by applicable law or agreed to in writing, software
 12  
  * distributed under the License is distributed on an "AS IS" BASIS,
 13  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 14  
  * See the License for the specific language governing permissions and
 15  
  * limitations under the License.
 16  
  */
 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.net.HttpURLConnection;
 25  
 import java.net.MalformedURLException;
 26  
 import java.net.ProtocolException;
 27  
 import java.net.URL;
 28  
 import java.util.Collection;
 29  
 
 30  
 import org.apache.ojb.broker.Identity;
 31  
 import org.apache.ojb.broker.PersistenceBroker;
 32  
 import org.apache.ojb.broker.PersistenceBrokerException;
 33  
 import org.apache.ojb.broker.util.configuration.Configurable;
 34  
 import org.apache.ojb.broker.util.configuration.Configuration;
 35  
 import org.apache.ojb.broker.util.configuration.ConfigurationException;
 36  
 import org.apache.ojb.broker.util.logging.Logger;
 37  
 import org.apache.ojb.broker.util.logging.LoggerFactory;
 38  
 import org.apache.ojb.odmg.TransactionImpl;
 39  
 import org.apache.ojb.odmg.TxManagerFactory;
 40  
 
 41  
 /**
 42  
  * Servlet based lock mechanism for usage in distributed environment.
 43  
  * @author Thomas Mahler
 44  
  * @version $Id: RemoteLockMapImpl.java,v 1.1 2007-08-24 22:17:28 ewestfal Exp $
 45  
  */
 46  
 public class RemoteLockMapImpl implements LockMap, Configurable
 47  
 {
 48  
         private Logger log = LoggerFactory.getLogger(RemoteLockMapImpl.class);
 49  
         
 50  
         private static URL lockservlet = null;
 51  
 
 52  
         /**
 53  
          * obtain a PersistenceBroker instance.
 54  
          */
 55  
         private PersistenceBroker getBroker()
 56  
         {
 57  
                 return TxManagerFactory.instance().getCurrentTransaction().getBroker();
 58  
         }
 59  
 
 60  
         /**
 61  
          * returns the LockEntry for the Writer of object obj.
 62  
          * If now writer exists, null is returned.
 63  
          */
 64  
         public LockEntry getWriter(Object obj)
 65  
         {
 66  
                 PersistenceBroker broker = getBroker();
 67  
                 Identity oid = new Identity(obj, broker);
 68  
                 
 69  
         LockEntry result = null;
 70  
         try
 71  
         {
 72  
                 result = getWriterRemote(oid);
 73  
         }
 74  
         catch (Throwable e)
 75  
         {
 76  
                 log.error(e);
 77  
         }
 78  
                 return result;
 79  
         }
 80  
 
 81  
     private LockEntry getWriterRemote(Identity oid)
 82  
         throws
 83  
             MalformedURLException,
 84  
             IOException,
 85  
             ProtocolException,
 86  
             ClassNotFoundException
 87  
     {
 88  
             byte selector = (byte) 'w';
 89  
         byte[] requestBarr = buildRequestArray(oid, selector);
 90  
         
 91  
         HttpURLConnection conn = getHttpUrlConnection();
 92  
         
 93  
         //post request
 94  
         BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 95  
         out.write(requestBarr,0,requestBarr.length);
 96  
         out.flush();
 97  
         out.close();                
 98  
         
 99  
         // read result from 
 100  
         InputStream in = conn.getInputStream();
 101  
         ObjectInputStream ois = new ObjectInputStream(in);
 102  
         LockEntry result = (LockEntry) ois.readObject();
 103  
         
 104  
         // cleanup
 105  
         ois.close();
 106  
         conn.disconnect();
 107  
         return result;
 108  
     }
 109  
 
 110  
     private HttpURLConnection getHttpUrlConnection()
 111  
         throws MalformedURLException, IOException, ProtocolException
 112  
     {
 113  
         URL lockserver = getLockserverUrl();
 114  
         HttpURLConnection conn= (HttpURLConnection) lockserver.openConnection();
 115  
         
 116  
         conn.setDoInput(true);
 117  
         conn.setDoOutput(true);
 118  
         conn.setRequestMethod("POST");
 119  
         conn.setAllowUserInteraction(false);
 120  
         conn.setUseCaches(false);
 121  
         return conn;
 122  
     }
 123  
 
 124  
     private byte[] buildRequestArray(Object object, byte selector) throws IOException
 125  
     {
 126  
         byte[] serialObj = serialize(object);
 127  
         int len = serialObj.length; 
 128  
         byte[] requestBarr = new byte[len + 1];
 129  
         requestBarr[0] = selector;
 130  
         System.arraycopy(serialObj,0,requestBarr,1,len);
 131  
         return requestBarr;
 132  
     }
 133  
 
 134  
 
 135  
     private URL getLockserverUrl() throws MalformedURLException
 136  
     {
 137  
         return lockservlet;
 138  
     }
 139  
 
 140  
 
 141  
 
 142  
         /**
 143  
          * returns a collection of Reader LockEntries for object obj.
 144  
          * If now LockEntries could be found an empty Vector is returned.
 145  
          */
 146  
         public Collection getReaders(Object obj)
 147  
         {
 148  
                 Collection result = null;
 149  
         try
 150  
         {
 151  
             Identity oid = new Identity(obj, getBroker());
 152  
             byte selector = (byte) 'r';
 153  
             byte[] requestBarr = buildRequestArray(oid, selector);
 154  
             
 155  
             HttpURLConnection conn = getHttpUrlConnection();
 156  
             
 157  
             //post request
 158  
             BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 159  
             out.write(requestBarr,0,requestBarr.length);
 160  
             out.flush();                
 161  
             
 162  
             // read result from 
 163  
             InputStream in = conn.getInputStream();
 164  
             ObjectInputStream ois = new ObjectInputStream(in);
 165  
             result = (Collection) ois.readObject();
 166  
             
 167  
             // cleanup
 168  
             ois.close();
 169  
             out.close();
 170  
             conn.disconnect();                
 171  
         }
 172  
         catch (Throwable t)
 173  
         {
 174  
             throw new PersistenceBrokerException(t);
 175  
         }
 176  
         return result;
 177  
         }
 178  
 
 179  
 
 180  
         /**
 181  
          * Add a reader lock entry for transaction tx on object obj
 182  
          * to the persistent storage.
 183  
          */
 184  
         public boolean addReader(TransactionImpl tx, Object obj)
 185  
         {
 186  
                 try
 187  
                 {
 188  
                         LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(),
 189  
                                         tx.getGUID(),
 190  
                                         System.currentTimeMillis(),
 191  
                                         LockStrategyFactory.getIsolationLevel(obj),
 192  
                                         LockEntry.LOCK_READ);
 193  
             addReaderRemote(lock);
 194  
                         return true;
 195  
                 }
 196  
                 catch (Throwable t)
 197  
                 {
 198  
                         log.error("Cannot store LockEntry for object " + obj + " in transaction " + tx, t);
 199  
                         return false;
 200  
                 }
 201  
         }
 202  
 
 203  
     private void addReaderRemote(LockEntry lock) throws IOException, ClassNotFoundException
 204  
     {
 205  
                 byte selector = (byte) 'a';
 206  
                 byte[] requestBarr = buildRequestArray(lock,selector);
 207  
         
 208  
                 HttpURLConnection conn = getHttpUrlConnection();
 209  
         
 210  
                 //post request
 211  
                 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 212  
                 out.write(requestBarr,0,requestBarr.length);
 213  
                 out.flush();                
 214  
         
 215  
                 // read result from 
 216  
                 InputStream in = conn.getInputStream();
 217  
                 ObjectInputStream ois = new ObjectInputStream(in);
 218  
                 Boolean result = (Boolean) ois.readObject();
 219  
         
 220  
                 // cleanup
 221  
                 ois.close();
 222  
                 out.close();
 223  
                 conn.disconnect();
 224  
                 if (! result.booleanValue())
 225  
                 {
 226  
                         throw new PersistenceBrokerException("could not add reader!");                
 227  
                 }
 228  
     }
 229  
 
 230  
         public byte[] serialize(Object obj) throws IOException
 231  
         {
 232  
                 ByteArrayOutputStream bao = new ByteArrayOutputStream();
 233  
                 ObjectOutputStream oos = new ObjectOutputStream(bao);
 234  
                 oos.writeObject(obj);
 235  
                 oos.close();
 236  
                 bao.close();
 237  
                 byte[] result = bao.toByteArray();
 238  
                 return result;
 239  
         }
 240  
 
 241  
         /**
 242  
          * remove a reader lock entry for transaction tx on object obj
 243  
          * from the persistent storage.
 244  
          */
 245  
         public void removeReader(TransactionImpl tx, Object obj)
 246  
         {
 247  
                 try
 248  
                 {
 249  
                         LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(), tx.getGUID());
 250  
             removeReaderRemote(lock);
 251  
                 }
 252  
                 catch (Throwable t)
 253  
                 {
 254  
                         log.error("Cannot remove LockEntry for object " + obj + " in transaction " + tx);
 255  
                 }
 256  
         }
 257  
 
 258  
     private void removeReaderRemote(LockEntry lock) throws IOException, ClassNotFoundException
 259  
     {
 260  
                 byte selector = (byte) 'e';
 261  
                 byte[] requestBarr = buildRequestArray(lock,selector);
 262  
         
 263  
                 HttpURLConnection conn = getHttpUrlConnection();
 264  
         
 265  
                 //post request
 266  
                 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 267  
                 out.write(requestBarr,0,requestBarr.length);
 268  
                 out.flush();                
 269  
         
 270  
                 // read result from 
 271  
                 InputStream in = conn.getInputStream();
 272  
                 ObjectInputStream ois = new ObjectInputStream(in);
 273  
                 Boolean result = (Boolean) ois.readObject();
 274  
         
 275  
                 // cleanup
 276  
                 ois.close();
 277  
                 out.close();
 278  
                 conn.disconnect();
 279  
                 if (! result.booleanValue())
 280  
                 {
 281  
                         throw new PersistenceBrokerException("could not remove reader!");                
 282  
                 }
 283  
 
 284  
     }
 285  
 
 286  
         /**
 287  
          * remove a writer lock entry for transaction tx on object obj
 288  
          * from the persistent storage.
 289  
          */
 290  
         public void removeWriter(LockEntry writer)
 291  
         {
 292  
                 try
 293  
                 {
 294  
                         removeWriterRemote(writer);
 295  
                 }
 296  
                 catch (Throwable t)
 297  
                 {
 298  
                         log.error("Cannot remove LockEntry", t);
 299  
                 }
 300  
         }
 301  
 
 302  
         private void removeWriterRemote(LockEntry lock) throws IOException, ClassNotFoundException
 303  
         {
 304  
                 byte selector = (byte) 'm';
 305  
                 byte[] requestBarr = buildRequestArray(lock,selector);
 306  
         
 307  
                 HttpURLConnection conn = getHttpUrlConnection();
 308  
         
 309  
                 //post request
 310  
                 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 311  
                 out.write(requestBarr,0,requestBarr.length);
 312  
                 out.flush();                
 313  
         
 314  
                 // read result from 
 315  
                 InputStream in = conn.getInputStream();
 316  
                 ObjectInputStream ois = new ObjectInputStream(in);
 317  
                 Boolean result = (Boolean) ois.readObject();
 318  
         
 319  
                 // cleanup
 320  
                 ois.close();
 321  
                 out.close();
 322  
                 conn.disconnect();
 323  
                 if (! result.booleanValue())
 324  
                 {
 325  
                         throw new PersistenceBrokerException("could not remove writer!");                
 326  
                 }
 327  
 
 328  
         }
 329  
 
 330  
         /**
 331  
          * upgrade a reader lock entry for transaction tx on object obj
 332  
          * and write it to the persistent storage.
 333  
          */
 334  
         public boolean upgradeLock(LockEntry reader)
 335  
         {
 336  
                 try
 337  
                 {
 338  
                         upgradeLockRemote(reader);
 339  
                         reader.setLockType(LockEntry.LOCK_WRITE);
 340  
                         return true;
 341  
                 }
 342  
                 catch (Throwable t)
 343  
                 {
 344  
                         log.error("Cannot upgrade LockEntry " + reader, t);
 345  
                         return false;
 346  
                 }
 347  
         }
 348  
 
 349  
         private void upgradeLockRemote(LockEntry lock) throws IOException, ClassNotFoundException
 350  
         {
 351  
                 byte selector = (byte) 'u';
 352  
                 byte[] requestBarr = buildRequestArray(lock,selector);
 353  
         
 354  
                 HttpURLConnection conn = getHttpUrlConnection();
 355  
         
 356  
                 //post request
 357  
                 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 358  
                 out.write(requestBarr,0,requestBarr.length);
 359  
                 out.flush();                
 360  
         
 361  
                 // read result from 
 362  
                 InputStream in = conn.getInputStream();
 363  
                 ObjectInputStream ois = new ObjectInputStream(in);
 364  
                 Boolean result = (Boolean) ois.readObject();
 365  
         
 366  
                 // cleanup
 367  
                 ois.close();
 368  
                 out.close();
 369  
                 conn.disconnect();
 370  
                 if (! result.booleanValue())
 371  
                 {
 372  
                         throw new PersistenceBrokerException("could not remove writer!");                
 373  
                 }
 374  
 
 375  
         }
 376  
 
 377  
         /**
 378  
          * generate a writer lock entry for transaction tx on object obj
 379  
          * and write it to the persistent storage.
 380  
          */
 381  
         public boolean setWriter(TransactionImpl tx, Object obj)
 382  
         {
 383  
                 try
 384  
                 {
 385  
                         LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(),
 386  
                                         tx.getGUID(),
 387  
                                         System.currentTimeMillis(),
 388  
                                         LockStrategyFactory.getIsolationLevel(obj),
 389  
                                         LockEntry.LOCK_WRITE);
 390  
 
 391  
                         setWriterRemote(lock);
 392  
                         return true;
 393  
                 }
 394  
                 catch (Throwable t)
 395  
                 {
 396  
                         log.error("Cannot set LockEntry for object " + obj + " in transaction " + tx);
 397  
                         return false;
 398  
                 }
 399  
         }
 400  
 
 401  
         private void setWriterRemote(LockEntry lock) throws IOException, ClassNotFoundException
 402  
         {
 403  
                 byte selector = (byte) 's';
 404  
                 byte[] requestBarr = buildRequestArray(lock,selector);
 405  
         
 406  
                 HttpURLConnection conn = getHttpUrlConnection();
 407  
         
 408  
                 //post request
 409  
                 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 410  
                 out.write(requestBarr,0,requestBarr.length);
 411  
                 out.flush();                
 412  
         
 413  
                 // read result from 
 414  
                 InputStream in = conn.getInputStream();
 415  
                 ObjectInputStream ois = new ObjectInputStream(in);
 416  
                 Boolean result = (Boolean) ois.readObject();
 417  
         
 418  
                 // cleanup
 419  
                 ois.close();
 420  
                 out.close();
 421  
                 conn.disconnect();
 422  
                 if (! result.booleanValue())
 423  
                 {
 424  
                         throw new PersistenceBrokerException("could not set writer!");                
 425  
                 }
 426  
 
 427  
         }
 428  
 
 429  
         /**
 430  
          * check if there is a reader lock entry for transaction tx on object obj
 431  
          * in the persistent storage.
 432  
          */
 433  
         public boolean hasReadLock(TransactionImpl tx, Object obj)
 434  
         {
 435  
                 try
 436  
                 {
 437  
                         LockEntry lock = new LockEntry(new Identity(obj,getBroker()).toString(), tx.getGUID());
 438  
                         boolean result = hasReadLockRemote(lock);                        
 439  
                         return result;
 440  
                 }
 441  
                 catch (Throwable t)
 442  
                 {
 443  
                         log.error("Cannot check read lock for object " + obj + " in transaction " + tx, t);
 444  
                         return false;
 445  
                 }
 446  
         }
 447  
 
 448  
         private boolean hasReadLockRemote(LockEntry lock) throws IOException, ClassNotFoundException
 449  
         {
 450  
                 byte selector = (byte) 'h';
 451  
                 byte[] requestBarr = buildRequestArray(lock,selector);
 452  
         
 453  
                 HttpURLConnection conn = getHttpUrlConnection();
 454  
         
 455  
                 //post request
 456  
                 BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 457  
                 out.write(requestBarr,0,requestBarr.length);
 458  
                 out.flush();                
 459  
         
 460  
                 // read result from 
 461  
                 InputStream in = conn.getInputStream();
 462  
                 ObjectInputStream ois = new ObjectInputStream(in);
 463  
                 Boolean result = (Boolean) ois.readObject();
 464  
         
 465  
                 // cleanup
 466  
                 ois.close();
 467  
                 out.close();
 468  
                 conn.disconnect();
 469  
                 return result.booleanValue();
 470  
         }
 471  
 
 472  
 
 473  
 
 474  
         
 475  
     /**
 476  
      * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration)
 477  
      */
 478  
     public void configure(Configuration pConfig) throws ConfigurationException
 479  
     {
 480  
         String url = pConfig.getString("LockServletUrl","http://127.0.0.1:8080/ojb-lockserver");
 481  
         try
 482  
         {
 483  
             lockservlet = new URL(url);
 484  
         }
 485  
         catch (MalformedURLException e)
 486  
         {
 487  
             throw new ConfigurationException("Invalid LockServlet Url was specified: " + url, e);
 488  
         }
 489  
 
 490  
     }
 491  
 
 492  
 }