View Javadoc

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