EMMA Coverage Report (generated Mon Oct 17 05:41:20 EDT 2011)
[all classes][org.jclouds.atmos.blobstore.strategy]

COVERAGE SUMMARY FOR SOURCE FILE [FindMD5InUserMetadata.java]

nameclass, %method, %block, %line, %
FindMD5InUserMetadata.java50%  (1/2)25%  (1/4)8%   (18/224)19%  (7/37)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FindMD5InUserMetadata$10%   (0/1)0%   (0/2)0%   (0/73)0%   (0/13)
FindMD5InUserMetadata$1 (FindMD5InUserMetadata, ListenableFuture, byte [], Bl... 0%   (0/1)0%   (0/15)0%   (0/1)
run (): void 0%   (0/1)0%   (0/58)0%   (0/12)
     
class FindMD5InUserMetadata100% (1/1)50%  (1/2)12%  (18/151)28%  (7/25)
execute (String, Object, ListContainerOptions): boolean 0%   (0/1)0%   (0/133)0%   (0/18)
FindMD5InUserMetadata (ExecutorService, ObjectMD5, ListBlobsInContainer, Atmo... 100% (1/1)100% (18/18)100% (7/7)

1/**
2 * Licensed to jclouds, Inc. (jclouds) under one or more
3 * contributor license agreements.  See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership.  jclouds licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License.  You may obtain a copy of the License at
9 *
10 *   http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19package org.jclouds.atmos.blobstore.strategy;
20 
21import static com.google.common.base.Preconditions.checkNotNull;
22import static org.jclouds.concurrent.FutureIterables.awaitCompletion;
23 
24import java.util.Arrays;
25import java.util.Map;
26import java.util.concurrent.BlockingQueue;
27import java.util.concurrent.ExecutionException;
28import java.util.concurrent.ExecutorService;
29import java.util.concurrent.Future;
30import java.util.concurrent.SynchronousQueue;
31import java.util.concurrent.TimeUnit;
32 
33import javax.annotation.Resource;
34import javax.inject.Named;
35import javax.inject.Singleton;
36 
37import org.jclouds.Constants;
38import org.jclouds.atmos.AtmosAsyncClient;
39import org.jclouds.atmos.domain.AtmosObject;
40import org.jclouds.blobstore.domain.BlobMetadata;
41import org.jclouds.blobstore.functions.ObjectMD5;
42import org.jclouds.blobstore.internal.BlobRuntimeException;
43import org.jclouds.blobstore.options.ListContainerOptions;
44import org.jclouds.blobstore.strategy.ContainsValueInListStrategy;
45import org.jclouds.blobstore.strategy.ListBlobsInContainer;
46import org.jclouds.concurrent.Futures;
47import org.jclouds.logging.Logger;
48 
49import com.google.common.base.Throwables;
50import com.google.common.collect.Maps;
51import com.google.common.util.concurrent.ListenableFuture;
52import com.google.inject.Inject;
53 
54/**
55 * Searches Content-MD5 tag for the value associated with the value
56 * 
57 * @author Adrian Cole
58 */
59@Singleton
60public class FindMD5InUserMetadata implements ContainsValueInListStrategy {
61   @Resource
62   protected Logger logger = Logger.NULL;
63   protected final ObjectMD5 objectMD5;
64   protected final ListBlobsInContainer getAllBlobMetadata;
65   private final AtmosAsyncClient client;
66   private final ExecutorService userExecutor;
67   /**
68    * maximum duration of an blob Request
69    */
70   @Inject(optional = true)
71   @Named(Constants.PROPERTY_REQUEST_TIMEOUT)
72   protected Long maxTime;
73 
74   @Inject
75   FindMD5InUserMetadata(@Named(Constants.PROPERTY_USER_THREADS) ExecutorService userExecutor, ObjectMD5 objectMD5,
76         ListBlobsInContainer getAllBlobMetadata, AtmosAsyncClient client) {
77      this.objectMD5 = objectMD5;
78      this.getAllBlobMetadata = getAllBlobMetadata;
79      this.client = client;
80      this.userExecutor = userExecutor;
81   }
82 
83   @Override
84   public boolean execute(final String containerName, Object value, ListContainerOptions options) {
85      final byte[] toSearch = objectMD5.apply(value);
86      final BlockingQueue<Boolean> queue = new SynchronousQueue<Boolean>();
87      Map<String, Future<?>> responses = Maps.newHashMap();
88      for (BlobMetadata md : getAllBlobMetadata.execute(containerName, options)) {
89         final ListenableFuture<AtmosObject> future = Futures.makeListenable(
90               client.headFile(containerName + "/" + md.getName()), userExecutor);
91         future.addListener(new Runnable() {
92            public void run() {
93               try {
94                  AtmosObject object = future.get();
95                  checkNotNull(object.getSystemMetadata(), object + " has no content metadata");
96                  if (object.getSystemMetadata().getContentMD5() != null) {
97                     if (Arrays.equals(toSearch, object.getSystemMetadata().getContentMD5())) {
98                        queue.put(true);
99                     }
100                  } else {
101                     logger.debug("object %s has no content md5", object.getSystemMetadata().getObjectID());
102                  }
103               } catch (InterruptedException e) {
104                  Throwables.propagate(e);
105               } catch (ExecutionException e) {
106                  Throwables.propagate(e);
107               }
108            }
109         }, userExecutor);
110         responses.put(md.getName(), future);
111      }
112      Map<String, Exception> exceptions = awaitCompletion(responses, userExecutor, maxTime, logger,
113            String.format("searching for md5 in container %s", containerName));
114      if (exceptions.size() > 0)
115         throw new BlobRuntimeException(String.format("searching for md5 in container %s: %s", containerName,
116               exceptions));
117      try {
118         return queue.poll(1, TimeUnit.MICROSECONDS) != null;
119      } catch (InterruptedException e) {
120         Throwables.propagate(e);
121         return false;
122      } catch (Exception e) {
123         Throwables.propagateIfPossible(e, BlobRuntimeException.class);
124         throw new BlobRuntimeException(String.format("Error searching for ETAG of value: [%s] in container:%s", value,
125               containerName), e);
126      }
127   }
128}

[all classes][org.jclouds.atmos.blobstore.strategy]
EMMA 2.0.5312 (C) Vladimir Roubtsov