Coverage Report - org.apache.ojb.broker.locking.LockManagerRemoteImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
LockManagerRemoteImpl
N/A
N/A
2.8
LockManagerRemoteImpl$LockInfo
N/A
N/A
2.8
 
 1  
 package org.apache.ojb.broker.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.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  
 /**
 37  
  * This implementation of the {@link LockManager} interface supports locking
 38  
  * in distributed environments in combination with a specific lock servlet.
 39  
  *
 40  
  * @see LockManagerServlet
 41  
  * @version $Id: LockManagerRemoteImpl.java,v 1.1 2007-08-24 22:17:41 ewestfal Exp $
 42  
  */
 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  
     /**
 68  
      * @see org.apache.ojb.broker.util.configuration.Configurable#configure(org.apache.ojb.broker.util.configuration.Configuration)
 69  
      */
 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  
     /**
 86  
      * noop
 87  
      * @param timeout
 88  
      */
 89  
     public void setLockTimeout(long timeout)
 90  
     {
 91  
 //        LockInfo info = new LockInfo(timeout, METHOD_LOCK_TIMEOUT_SET);
 92  
 //        try
 93  
 //        {
 94  
 //            byte[] requestBarr = serialize(info);
 95  
 //            performRequestObject(requestBarr);
 96  
 //        }
 97  
 //        catch(Throwable t)
 98  
 //        {
 99  
 //            throw new LockRuntimeException("Can't set locking timeout", t);
 100  
 //        }
 101  
     }
 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  
     /**
 132  
      * noop
 133  
      */ 
 134  
     public void setBlockTimeout(long timeout)
 135  
     {
 136  
 //        LockInfo info = new LockInfo(timeout, METHOD_BLOCK_TIMEOUT_SET);
 137  
 //        try
 138  
 //        {
 139  
 //            byte[] requestBarr = serialize(info);
 140  
 //            performRequestObject(requestBarr);
 141  
 //        }
 142  
 //        catch(Throwable t)
 143  
 //        {
 144  
 //            throw new LockRuntimeException("Can't set block timeout value", t);
 145  
 //        }
 146  
     }
 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  
 //    public boolean removeReader(Object key, Object resourceId)
 193  
 //    {
 194  
 //        LockInfo info = new LockInfo(key, resourceId, METHOD_RELEASE_SINGLE_LOCK);
 195  
 //        try
 196  
 //        {
 197  
 //            byte[] requestBarr = serialize(info);
 198  
 //            return performRequest(requestBarr);
 199  
 //        }
 200  
 //        catch(Throwable t)
 201  
 //        {
 202  
 //            throw new LockRuntimeException("Cannot remove read lock for '"
 203  
 //                    + resourceId + "' using key '" + key + "'", t);
 204  
 //        }
 205  
 //    }
 206  
 
 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  
         //post request
 367  
         BufferedOutputStream out = new BufferedOutputStream(conn.getOutputStream());
 368  
         out.write(requestBarr, 0, requestBarr.length);
 369  
         out.flush();
 370  
 
 371  
         // read result from
 372  
         InputStream in = conn.getInputStream();
 373  
         ObjectInputStream ois = new ObjectInputStream(in);
 374  
         Object result = ois.readObject();
 375  
 
 376  
         // cleanup
 377  
         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  
 //        public LockInfo(long timeout, byte methodName)
 421  
 //        {
 422  
 //            if(methodName == METHOD_LOCK_TIMEOUT_SET)
 423  
 //            {
 424  
 //                this.lockTimeout = timeout;
 425  
 //            }
 426  
 //            else
 427  
 //            {
 428  
 //                this.blockTimeout = timeout;
 429  
 //            }
 430  
 //            this.methodName = methodName;
 431  
 //        }
 432  
     }
 433  
 }