Author: chetanm
Date: Wed Dec 23 06:23:29 2015
New Revision: 1721494

URL: http://svn.apache.org/viewvc?rev=1721494&view=rev
Log:
OAK-3806 - Collect and expose statistics related to BlobStore operations

Add support in AbstractBlobStore

Added:
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStatsCollector.java
   (with props)
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStoreStatsMBean.java
   (with props)
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreams.java
   (with props)
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/package-info.java
   (with props)
    
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/StatsCollectorTest.java
   (with props)
    
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/
    
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreamsTest.java
   (with props)
Modified:
    jackrabbit/oak/trunk/oak-blob/pom.xml
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/AbstractBlobStore.java
    
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/package-info.java

Modified: jackrabbit/oak/trunk/oak-blob/pom.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/pom.xml?rev=1721494&r1=1721493&r2=1721494&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-blob/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-blob/pom.xml Wed Dec 23 06:23:29 2015
@@ -46,6 +46,7 @@
             </Import-Package>
             <Export-Package>
               org.apache.jackrabbit.oak.spi.blob,
+              org.apache.jackrabbit.oak.spi.blob.stats,
               org.apache.jackrabbit.oak.spi.blob.split
             </Export-Package>
           </instructions>
@@ -148,6 +149,11 @@
       <classifier>tests</classifier>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>ch.qos.logback</groupId>
+      <artifactId>logback-classic</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>

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=1721494&r1=1721493&r2=1721494&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 Dec 23 06:23:29 2015
@@ -37,6 +37,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
 import java.util.WeakHashMap;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 import javax.annotation.Nonnull;
@@ -45,10 +46,13 @@ import javax.crypto.spec.SecretKeySpec;
 
 import com.google.common.base.Charsets;
 import com.google.common.io.BaseEncoding;
+import com.google.common.io.CountingInputStream;
 import org.apache.commons.io.FileUtils;
 import org.apache.jackrabbit.oak.commons.cache.Cache;
 import org.apache.jackrabbit.oak.commons.IOUtils;
 import org.apache.jackrabbit.oak.commons.StringUtils;
+import org.apache.jackrabbit.oak.spi.blob.stats.StatsCollectingStreams;
+import org.apache.jackrabbit.oak.spi.blob.stats.BlobStatsCollector;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -135,6 +139,8 @@ public abstract class AbstractBlobStore
 
     private final Logger log = LoggerFactory.getLogger(getClass());
 
+    private BlobStatsCollector stats = BlobStatsCollector.NOOP;
+
     public void setBlockSizeMin(int x) {
         validateBlockSize(x);
         this.blockSizeMin = x;
@@ -151,6 +157,10 @@ public abstract class AbstractBlobStore
         this.blockSize = x;
     }
 
+    public void setStatsCollector(BlobStatsCollector stats) {
+        this.stats = stats;
+    }
+
     private static void validateBlockSize(int x) {
         if (x < BLOCK_SIZE_LIMIT) {
             throw new IllegalArgumentException(
@@ -179,12 +189,16 @@ public abstract class AbstractBlobStore
     @Override
     public String writeBlob(InputStream in) throws IOException {
         try {
+            long start = System.nanoTime();
+            CountingInputStream cin = new CountingInputStream(in);
             ByteArrayOutputStream idStream = new ByteArrayOutputStream();
-            convertBlobToId(in, idStream, 0, 0);
+            convertBlobToId(cin, idStream, 0, 0);
             byte[] id = idStream.toByteArray();
             // System.out.println("    write blob " +  
StringUtils.convertBytesToHex(id));
             String blobId = StringUtils.convertBytesToHex(id);
             usesBlobId(blobId);
+
+            stats.uploaded(System.nanoTime() - start, TimeUnit.NANOSECONDS, 
cin.getCount());
             return blobId;
         } finally {
             try {
@@ -198,7 +212,7 @@ public abstract class AbstractBlobStore
     @Override
     public InputStream getInputStream(String blobId) throws IOException {
         //Marking would handled by next call to store.readBlob
-        return new BlobStoreInputStream(this, blobId, 0);
+        return StatsCollectingStreams.wrap(stats, blobId , new 
BlobStoreInputStream(this, blobId, 0));
     }
 
     //--------------------------------------------< Blob Reference >

Modified: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/package-info.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/package-info.java?rev=1721494&r1=1721493&r2=1721494&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/package-info.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/package-info.java
 Wed Dec 23 06:23:29 2015
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.2")
+@Version("1.3.0")
 @Export(optional = "provide:=true")
 package org.apache.jackrabbit.oak.spi.blob;
 

Added: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStatsCollector.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStatsCollector.java?rev=1721494&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStatsCollector.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStatsCollector.java
 Wed Dec 23 06:23:29 2015
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.blob.stats;
+
+import java.util.concurrent.TimeUnit;
+
+import aQute.bnd.annotation.ConsumerType;
+
+/**
+ * BlobStoreStatsCollector receives callback when blobs are written and read
+ * from BlobStore
+ */
+@ConsumerType
+public interface BlobStatsCollector {
+    BlobStatsCollector NOOP = new BlobStatsCollector() {
+        @Override
+        public void uploaded(long timeTaken, TimeUnit unit, long size) {
+
+        }
+
+        @Override
+        public void downloaded(String blobId, long timeTaken, TimeUnit unit, 
long size) {
+
+        }
+    };
+
+    /**
+     * Called when a binary content is written to BlobStore
+     *
+     * @param timeTaken time taken to perform the operation
+     * @param unit unit of time taken
+     * @param size size of binary content being written
+     */
+    void uploaded(long timeTaken, TimeUnit unit, long size);
+
+    /**
+     * Called when a binary content is read from BlobStore
+     *
+     * @param blobId id of blob whose content are being read
+     * @param timeTaken time taken to perform the operation
+     * @param unit unit of time taken
+     * @param size size of binary content being read
+     */
+    void downloaded(String blobId, long timeTaken, TimeUnit unit, long size);
+}

Propchange: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStatsCollector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStoreStatsMBean.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStoreStatsMBean.java?rev=1721494&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStoreStatsMBean.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStoreStatsMBean.java
 Wed Dec 23 06:23:29 2015
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.blob.stats;
+
+import javax.management.openmbean.CompositeData;
+
+import aQute.bnd.annotation.ProviderType;
+
+@ProviderType
+public interface BlobStoreStatsMBean {
+    String TYPE = "BlobStoreStats";
+
+    long getUploadTotalSize();
+
+    long getUploadCount();
+
+    long getUploadTotalSeconds();
+
+    long getDownloadTotalSize();
+
+    long getDownloadCount();
+
+    long getDownloadTotalSeconds();
+
+    String blobStoreInfoAsString();
+
+    CompositeData getUploadSizeHistory();
+
+    CompositeData getDownloadSizeHistory();
+}

Propchange: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/BlobStoreStatsMBean.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreams.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreams.java?rev=1721494&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreams.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreams.java
 Wed Dec 23 06:23:29 2015
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.blob.stats;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.io.CountingInputStream;
+
+
+public final class StatsCollectingStreams {
+
+    public static InputStream wrap(final BlobStatsCollector collector, final 
String blobId, InputStream in) {
+        final CountingInputStream cin = new CountingInputStream(in);
+        return new FilterInputStream(cin) {
+            final long startTime = System.nanoTime();
+
+            @Override
+            public void close() throws IOException {
+                super.close();
+                //We rely on close to determine how much was downloaded
+                //as once an InputStream is exposed its not possible to
+                //determine if the stream is actually used
+
+                //Download time might not be accurate as reading code might
+                //be processing also as it moved further in stream. So that
+                //overhead would add to the download time
+
+                collector.downloaded(blobId, System.nanoTime() - startTime, 
TimeUnit.NANOSECONDS, cin.getCount());
+            }
+        };
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreams.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/package-info.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/package-info.java?rev=1721494&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/package-info.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/package-info.java
 Wed Dec 23 06:23:29 2015
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+@Version("1.0.0")
+@Export(optional = "provide:=true")
+package org.apache.jackrabbit.oak.spi.blob.stats;
+
+import aQute.bnd.annotation.Export;
+import aQute.bnd.annotation.Version;

Propchange: 
jackrabbit/oak/trunk/oak-blob/src/main/java/org/apache/jackrabbit/oak/spi/blob/stats/package-info.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/StatsCollectorTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/StatsCollectorTest.java?rev=1721494&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/StatsCollectorTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/StatsCollectorTest.java
 Wed Dec 23 06:23:29 2015
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.blob;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Random;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.output.CountingOutputStream;
+import org.apache.commons.io.output.NullOutputStream;
+import org.apache.jackrabbit.oak.spi.blob.stats.BlobStatsCollector;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class StatsCollectorTest {
+    private BlobStore store;
+    private TestCollector collector = new TestCollector();
+
+    @Before
+    public void setupStore(){
+        store = createBlobStore(collector);
+    }
+
+    protected BlobStore createBlobStore(BlobStatsCollector collector) {
+        MemoryBlobStore store = new MemoryBlobStore();
+        store.setStatsCollector(collector);
+        return store;
+    }
+
+    @Test
+    public void uploadCallback() throws Exception {
+        store.writeBlob(testStream(1042));
+        assertEquals(1042, collector.size);
+    }
+
+    @Test
+    public void downloadCallback() throws Exception {
+        String id = store.writeBlob(testStream(1042));
+
+        collector.size = 0;
+        InputStream is = store.getInputStream(id);
+        CountingOutputStream cos = new CountingOutputStream(new 
NullOutputStream());
+        IOUtils.copy(is, cos);
+        is.close();
+
+        assertEquals(1042, cos.getCount());
+        assertEquals(1042, collector.size);
+    }
+
+    private InputStream testStream(int size) {
+        //Cannot use NullInputStream as it throws exception upon EOF
+        byte[] data = new byte[size];
+        new Random().nextBytes(data);
+        return new ByteArrayInputStream(data);
+    }
+
+    private static class TestCollector implements BlobStatsCollector {
+        long size;
+
+        @Override
+        public void uploaded(long timeTaken, TimeUnit unit, long size) {
+            this.size = size;
+        }
+
+        @Override
+        public void downloaded(String blobId, long timeTaken, TimeUnit unit, 
long size) {
+            this.size = size;
+        }
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/StatsCollectorTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreamsTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreamsTest.java?rev=1721494&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreamsTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreamsTest.java
 Wed Dec 23 06:23:29 2015
@@ -0,0 +1,70 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.jackrabbit.oak.spi.blob.stats;
+
+import java.io.InputStream;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.io.input.NullInputStream;
+import org.apache.commons.io.output.CountingOutputStream;
+import org.apache.commons.io.output.NullOutputStream;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class StatsCollectingStreamsTest {
+
+    @Test
+    public void downloadCallback() throws Exception {
+        NullInputStream in = new NullInputStream(1042);
+        TestCollector stats = new TestCollector();
+        InputStream wrappedStream = StatsCollectingStreams.wrap(stats, "foo", 
in);
+        assertEquals(0, stats.callbackCount);
+
+        //Copy the content to get size
+        CountingOutputStream cos = new CountingOutputStream(new 
NullOutputStream());
+        IOUtils.copy(wrappedStream, cos);
+
+        assertEquals(1042, cos.getCount());
+
+        //Stream not closed so no callback
+        assertEquals(0, stats.callbackCount);
+
+        wrappedStream.close();
+        assertEquals(1042, stats.size);
+    }
+
+    private static class TestCollector implements BlobStatsCollector {
+        long size = -1;
+        int callbackCount;
+
+        @Override
+        public void uploaded(long timeTaken, TimeUnit unit, long size) {
+
+        }
+
+        @Override
+        public void downloaded(String blobId, long timeTaken, TimeUnit unit, 
long size) {
+            callbackCount++;
+            this.size = size;
+        }
+    }
+}
\ No newline at end of file

Propchange: 
jackrabbit/oak/trunk/oak-blob/src/test/java/org/apache/jackrabbit/oak/spi/blob/stats/StatsCollectingStreamsTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to