@Test void normalizeRevisionAndExecuteWithRetries() throws Exception { final Revision latestRevision = new Revision(3); when(delegate.normalizeRevision(any(), any(), any())).thenReturn(completedFuture(latestRevision)); when(delegate.getFile(any(), any(), any(), any(Query.class))).thenReturn( exceptionallyCompletedFuture(new RevisionNotFoundException()), exceptionallyCompletedFuture(new RevisionNotFoundException()), completedFuture(Entry.ofJson(latestRevision, "/foo.json", "{ \"a\": \"b\" }"))); assertThat(dogma.getFile("foo", "bar", Revision.HEAD, Query.ofJson("/foo.json")).join()) .isEqualTo(Entry.ofJson(latestRevision, "/foo.json", "{ \"a\": \"b\" }")); verify(delegate, times(1)).normalizeRevision("foo", "bar", Revision.HEAD); verify(delegate, times(3)).getFile("foo", "bar", latestRevision, Query.ofJson("/foo.json")); verifyNoMoreInteractions(delegate); }
private <T> CompletableFuture<T> normalizeRevisionAndExecuteWithRetries( String projectName, String repositoryName, Revision revision, Function<Revision, CompletableFuture<T>> taskRunner) { return normalizeRevision(projectName, repositoryName, revision) .thenCompose(normRev -> executeWithRetries( new Supplier<CompletableFuture<T>>() { @Override public CompletableFuture<T> get() { return taskRunner.apply(normRev); } @Override public String toString() { return taskRunner + " with " + normRev; } }, (res, cause) -> cause != null && handleRevisionNotFound(projectName, repositoryName, normRev, cause))); }
ReplicationLagTolerantCentralDogma extends AbstractCentralDogma { private <T> CompletableFuture<T> normalizeRevisionAndExecuteWithRetries( String projectName, String repositoryName, Revision revision, Function<Revision, CompletableFuture<T>> taskRunner) { return normalizeRevision(projectName, repositoryName, revision) .thenCompose(normRev -> executeWithRetries( new Supplier<CompletableFuture<T>>() { @Override public CompletableFuture<T> get() { return taskRunner.apply(normRev); } @Override public String toString() { return taskRunner + " with " + normRev; } }, (res, cause) -> cause != null && handleRevisionNotFound(projectName, repositoryName, normRev, cause))); } }
ReplicationLagTolerantCentralDogma extends AbstractCentralDogma { private <T> CompletableFuture<T> normalizeRevisionAndExecuteWithRetries( String projectName, String repositoryName, Revision revision, Function<Revision, CompletableFuture<T>> taskRunner) { return normalizeRevision(projectName, repositoryName, revision) .thenCompose(normRev -> executeWithRetries( new Supplier<CompletableFuture<T>>() { @Override public CompletableFuture<T> get() { return taskRunner.apply(normRev); } @Override public String toString() { return taskRunner + " with " + normRev; } }, (res, cause) -> cause != null && handleRevisionNotFound(projectName, repositoryName, normRev, cause))); } ReplicationLagTolerantCentralDogma(ScheduledExecutorService executor, CentralDogma delegate,
                                              int maxRetries, long retryIntervalMillis,
                                              Supplier<?> currentReplicaHintSupplier); }
ReplicationLagTolerantCentralDogma extends AbstractCentralDogma { private <T> CompletableFuture<T> normalizeRevisionAndExecuteWithRetries( String projectName, String repositoryName, Revision revision, Function<Revision, CompletableFuture<T>> taskRunner) { return normalizeRevision(projectName, repositoryName, revision) .thenCompose(normRev -> executeWithRetries( new Supplier<CompletableFuture<T>>() { @Override public CompletableFuture<T> get() { return taskRunner.apply(normRev); } @Override public String toString() { return taskRunner + " with " + normRev; } }, (res, cause) -> cause != null && handleRevisionNotFound(projectName, repositoryName, normRev, cause))); } ReplicationLagTolerantCentralDogma(ScheduledExecutorService executor, CentralDogma delegate,
                                              int maxRetries, long retryIntervalMillis,
                                              Supplier<?> currentReplicaHintSupplier); @Override CompletableFuture<Void> createProject(String projectName); @Override CompletableFuture<Void> removeProject(String projectName); @Override CompletableFuture<Void> purgeProject(String projectName); @Override CompletableFuture<Void> unremoveProject(String projectName); @Override CompletableFuture<Set<String>> listProjects(); @Override CompletableFuture<Set<String>> listRemovedProjects(); @Override CompletableFuture<Void> createRepository(String projectName, String repositoryName); @Override CompletableFuture<Void> removeRepository(String projectName, String repositoryName); @Override CompletableFuture<Void> purgeRepository(String projectName, String repositoryName); @Override CompletableFuture<Void> unremoveRepository(String projectName, String repositoryName); @Override CompletableFuture<Map<String, RepositoryInfo>> listRepositories(String projectName); @Override CompletableFuture<Set<String>> listRemovedRepositories(String projectName); @Override CompletableFuture<Revision> normalizeRevision(
            String projectName, String repositoryName, Revision revision); @Override CompletableFuture<Map<String, EntryType>> listFiles(
            String projectName, String repositoryName, Revision revision, String pathPattern); @Override CompletableFuture<Entry<T>> getFile(
            String projectName, String repositoryName, Revision revision, Query<T> query); @Override CompletableFuture<Map<String, Entry<?>>> getFiles(
            String projectName, String repositoryName, Revision revision, String pathPattern); @Override CompletableFuture<MergedEntry<T>> mergeFiles(
            String projectName, String repositoryName, Revision revision,
            MergeQuery<T> mergeQuery); @Override CompletableFuture<List<Commit>> getHistory(
            String projectName, String repositoryName, Revision from,
            Revision to, String pathPattern); @Override CompletableFuture<Change<T>> getDiff(
            String projectName, String repositoryName, Revision from, Revision to, Query<T> query); @Override CompletableFuture<List<Change<?>>> getDiffs(
            String projectName, String repositoryName, Revision from, Revision to, String pathPattern); @Override CompletableFuture<List<Change<?>>> getPreviewDiffs(
            String projectName, String repositoryName, Revision baseRevision,
            Iterable<? extends Change<?>> changes); @Override CompletableFuture<PushResult> push(
            String projectName, String repositoryName, Revision baseRevision,
            String summary, String detail, Markup markup, Iterable<? extends Change<?>> changes); @Override CompletableFuture<PushResult> push(
            String projectName, String repositoryName, Revision baseRevision,
            Author author, String summary, String detail, Markup markup,
            Iterable<? extends Change<?>> changes); @Override CompletableFuture<Revision> watchRepository(
            String projectName, String repositoryName, Revision lastKnownRevision,
            String pathPattern, long timeoutMillis); @Override CompletableFuture<Entry<T>> watchFile(
            String projectName, String repositoryName, Revision lastKnownRevision,
            Query<T> query, long timeoutMillis); }
ReplicationLagTolerantCentralDogma extends AbstractCentralDogma { private <T> CompletableFuture<T> normalizeRevisionAndExecuteWithRetries( String projectName, String repositoryName, Revision revision, Function<Revision, CompletableFuture<T>> taskRunner) { return normalizeRevision(projectName, repositoryName, revision) .thenCompose(normRev -> executeWithRetries( new Supplier<CompletableFuture<T>>() { @Override public CompletableFuture<T> get() { return taskRunner.apply(normRev); } @Override public String toString() { return taskRunner + " with " + normRev; } }, (res, cause) -> cause != null && handleRevisionNotFound(projectName, repositoryName, normRev, cause))); } ReplicationLagTolerantCentralDogma(ScheduledExecutorService executor, CentralDogma delegate,
                                              int maxRetries, long retryIntervalMillis,
                                              Supplier<?> currentReplicaHintSupplier); @Override CompletableFuture<Void> createProject(String projectName); @Override CompletableFuture<Void> removeProject(String projectName); @Override CompletableFuture<Void> purgeProject(String projectName); @Override CompletableFuture<Void> unremoveProject(String projectName); @Override CompletableFuture<Set<String>> listProjects(); @Override CompletableFuture<Set<String>> listRemovedProjects(); @Override CompletableFuture<Void> createRepository(String projectName, String repositoryName); @Override CompletableFuture<Void> removeRepository(String projectName, String repositoryName); @Override CompletableFuture<Void> purgeRepository(String projectName, String repositoryName); @Override CompletableFuture<Void> unremoveRepository(String projectName, String repositoryName); @Override CompletableFuture<Map<String, RepositoryInfo>> listRepositories(String projectName); @Override CompletableFuture<Set<String>> listRemovedRepositories(String projectName); @Override CompletableFuture<Revision> normalizeRevision(
            String projectName, String repositoryName, Revision revision); @Override CompletableFuture<Map<String, EntryType>> listFiles(
            String projectName, String repositoryName, Revision revision, String pathPattern); @Override CompletableFuture<Entry<T>> getFile(
            String projectName, String repositoryName, Revision revision, Query<T> query); @Override CompletableFuture<Map<String, Entry<?>>> getFiles(
            String projectName, String repositoryName, Revision revision, String pathPattern); @Override CompletableFuture<MergedEntry<T>> mergeFiles(
            String projectName, String repositoryName, Revision revision,
            MergeQuery<T> mergeQuery); @Override CompletableFuture<List<Commit>> getHistory(
            String projectName, String repositoryName, Revision from,
            Revision to, String pathPattern); @Override CompletableFuture<Change<T>> getDiff(
            String projectName, String repositoryName, Revision from, Revision to, Query<T> query); @Override CompletableFuture<List<Change<?>>> getDiffs(
            String projectName, String repositoryName, Revision from, Revision to, String pathPattern); @Override CompletableFuture<List<Change<?>>> getPreviewDiffs(
            String projectName, String repositoryName, Revision baseRevision,
            Iterable<? extends Change<?>> changes); @Override CompletableFuture<PushResult> push(
            String projectName, String repositoryName, Revision baseRevision,
            String summary, String detail, Markup markup, Iterable<? extends Change<?>> changes); @Override CompletableFuture<PushResult> push(
            String projectName, String repositoryName, Revision baseRevision,
            Author author, String summary, String detail, Markup markup,
            Iterable<? extends Change<?>> changes); @Override CompletableFuture<Revision> watchRepository(
            String projectName, String repositoryName, Revision lastKnownRevision,
            String pathPattern, long timeoutMillis); @Override CompletableFuture<Entry<T>> watchFile(
            String projectName, String repositoryName, Revision lastKnownRevision,
            Query<T> query, long timeoutMillis);  }