Author: chetanm
Date: Wed Mar 26 08:03:45 2014
New Revision: 1581730

URL: http://svn.apache.org/r1581730
Log:
OAK-1604 - Support for signed references in Blob (WIP)

Initialize referenceKey upon first use

Modified:
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStore.java

Modified: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStore.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStore.java?rev=1581730&r1=1581729&r2=1581730&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStore.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStore.java
 Wed Mar 26 08:03:45 2014
@@ -27,6 +27,7 @@ import java.lang.ref.WeakReference;
 import java.security.InvalidKeyException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -49,6 +50,7 @@ import org.apache.jackrabbit.oak.commons
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -186,12 +188,14 @@ public abstract class AbstractBlobStore 
         return new BlobStoreInputStream(this, blobId, 0);
     }
 
+    //--------------------------------------------< Blob Reference >
+
     @Override
     public String getReference(String blobId) {
         checkNotNull(blobId, "BlobId must be specified");
         try {
             Mac mac = Mac.getInstance(ALGORITHM);
-            mac.init(new SecretKeySpec(referenceKey, ALGORITHM));
+            mac.init(new SecretKeySpec(getReferenceKey(), ALGORITHM));
             byte[] hash = mac.doFinal(blobId.getBytes("UTF-8"));
             return blobId + ':' + BaseEncoding.base32Hex().encode(hash);
         } catch (NoSuchAlgorithmException e) {
@@ -218,7 +222,43 @@ public abstract class AbstractBlobStore 
         return null;
     }
 
+    /**
+     * Returns the reference key of this blob store. If one does not already
+     * exist, it is automatically created in an implementation-specific way.
+     * The default implementation simply creates a temporary random key that's
+     * valid only until the data store gets restarted. Subclasses can override
+     * and/or decorate this method to support a more persistent reference key.
+     * <p>
+     * This method is called only once during the lifetime of a data store
+     * instance and the return value is cached in memory, so it's no problem
+     * if the implementation is slow.
+     *
+     * @return reference key
+     */
+    protected byte[] getOrCreateReferenceKey() {
+        byte[] referenceKeyValue = new byte[256];
+        new SecureRandom().nextBytes(referenceKeyValue);
+        log.info("Reference key is not specified for the BlobStore in use. 
Generating a random key. For stable " +
+                "reference ensure that reference key is specified");
+        return referenceKeyValue;
+    }
+
+    /**
+     * Returns the reference key of this data store. Synchronized to
+     * control concurrent access to the cached {@link #referenceKey} value.
+     *
+     * @return reference key
+     */
+    private synchronized byte[] getReferenceKey() {
+        if (referenceKey == null) {
+            referenceKey = getOrCreateReferenceKey();
+        }
+        return referenceKey;
+    }
+
     public void setReferenceKey(byte[] referenceKey) {
+        checkArgument(referenceKey == null, "Reference key already initialized 
by default means. " +
+                "To explicitly set it, setReferenceKey must be invoked before 
its first use");
         this.referenceKey = referenceKey;
     }
 
@@ -227,7 +267,7 @@ public abstract class AbstractBlobStore 
      * @param encodedKey base64 encoded key
      */
     public void setReferenceKeyEncoded(String encodedKey) {
-        this.referenceKey = BaseEncoding.base64().decode(encodedKey);
+        setReferenceKey(BaseEncoding.base64().decode(encodedKey));
     }
 
     /**
@@ -243,7 +283,7 @@ public abstract class AbstractBlobStore 
      * @see org.apache.jackrabbit.oak.commons.PropertiesUtil#populate(Object, 
java.util.Map, boolean)
      */
     public void setReferenceKeyPlainText(String textKey) {
-        this.referenceKey = textKey.getBytes(Charsets.UTF_8);
+        setReferenceKey(textKey.getBytes(Charsets.UTF_8));
     }
 
     protected void usesBlobId(String blobId) {


Reply via email to