View Javadoc

1   package com.atlassian.vcache.internal.core.service;
2   
3   import java.util.concurrent.Callable;
4   import java.util.concurrent.CompletableFuture;
5   import java.util.concurrent.ExecutionException;
6   import java.util.function.Consumer;
7   import javax.annotation.Nonnull;
8   
9   import com.atlassian.vcache.ExternalCache;
10  import com.atlassian.vcache.ExternalCacheException;
11  import com.atlassian.vcache.MarshallerException;
12  import com.atlassian.vcache.internal.core.VCacheUtils;
13  
14  import org.slf4j.Logger;
15  
16  import static com.atlassian.vcache.ExternalCacheException.Reason.MARSHALLER_FAILURE;
17  import static com.atlassian.vcache.ExternalCacheException.Reason.UNCLASSIFIED_FAILURE;
18  import static com.atlassian.vcache.internal.NameValidator.requireValidCacheName;
19  import static com.atlassian.vcache.internal.core.VCacheUtils.failed;
20  
21  /**
22   * Provides common operations for {@link ExternalCache} instances.
23   *
24   * @param <V> the value type
25   */
26  public abstract class AbstractExternalCache<V> implements ExternalCache<V>
27  {
28      protected final String name;
29  
30      protected AbstractExternalCache(String name)
31      {
32          this.name = requireValidCacheName(name);
33      }
34  
35      /**
36       * Returns the cache context for the current request.
37       * @return the cache context for the current request.
38       */
39      @Nonnull
40      protected abstract AbstractExternalCacheRequestContext<V> ensureCacheContext();
41  
42      /**
43       * Returns the logging instance for the implementation class.
44       * @return the logging instance for the implementation class.
45       */
46      @Nonnull
47      protected abstract Logger getLogger();
48  
49      /**
50       * Maps a generic {@link Exception} to a corresponding {@link ExternalCacheException}.
51       */
52      @Nonnull
53      protected abstract ExternalCacheException mapException(Exception ex);
54  
55      @Nonnull
56      @Override
57      public final String getName()
58      {
59          return name;
60      }
61  
62      /**
63       * Performs a transaction and handles all the standard exceptions that may occur.
64       *
65       * @param txn the transaction the perform
66       * @param <T> the return type
67       * @return A {@link CompletableFuture} representing the outcome of performing the transaction.
68       */
69      @Nonnull
70      protected <T> CompletableFuture<T> perform(Callable<T> txn)
71      {
72          return perform(txn, (i) -> {
73          });
74      }
75  
76      /**
77       * Performs a transaction and handles all the standard exceptions that may occur.
78       *
79       * @param txn the transaction the perform
80       * @param successHandler called if the <tt>txn</tt> is successful
81       * @param <T> the return type
82       * @return A {@link CompletableFuture} representing the outcome of performing the transaction.
83       */
84      @Nonnull
85      protected <T> CompletableFuture<T> perform(Callable<T> txn, Consumer<T> successHandler)
86      {
87          try
88          {
89              final T outcome = txn.call();
90              successHandler.accept(outcome);
91              return VCacheUtils.successful(outcome);
92          }
93          catch (MarshallerException ex)
94          {
95              return failed(new ExternalCacheException(MARSHALLER_FAILURE, ex));
96          }
97          catch (ExecutionException | InterruptedException ex)
98          {
99              return failed(new ExternalCacheException(UNCLASSIFIED_FAILURE, ex));
100         }
101         catch (ExternalCacheException ece)
102         {
103             return failed(ece);
104         }
105         catch (Exception ex)
106         {
107             return failed(mapException(ex));
108         }
109     }
110 }