/** * Creates a new instance. */ public <U> FileWatcher(CentralDogma client, ScheduledExecutorService executor, String projectName, String repositoryName, Query<U> query, Function<? super U, ? extends T> function) { super(client, executor, projectName, repositoryName, requireNonNull(query, "query").path()); this.query = unsafeCast(query); this.function = unsafeCast(requireNonNull(function, "function")); }
/** * Creates a new instance. */ public <U> FileWatcher(CentralDogma client, ScheduledExecutorService executor, String projectName, String repositoryName, Query<U> query, Function<? super U, ? extends T> function) { super(client, executor, projectName, repositoryName, requireNonNull(query, "query").path()); this.query = unsafeCast(query); this.function = unsafeCast(requireNonNull(function, "function")); }
/** * Creates a new instance. */ public <U> FileWatcher(CentralDogma client, ScheduledExecutorService executor, String projectName, String repositoryName, Query<U> query, Function<? super U, ? extends T> function) { super(client, executor, projectName, repositoryName, requireNonNull(query, "query").path()); this.query = unsafeCast(query); this.function = unsafeCast(requireNonNull(function, "function")); }
@Override protected Query doForward(com.linecorp.centraldogma.common.Query<?> query) { switch (query.type()) { case IDENTITY: return new Query(query.path(), QueryType.IDENTITY, Collections.emptyList()); case JSON_PATH: return new Query(query.path(), QueryType.JSON_PATH, query.expressions()); } throw new Error(); }
@Override protected Query doForward(com.linecorp.centraldogma.common.Query<?> query) { switch (query.type()) { case IDENTITY: return new Query(query.path(), QueryType.IDENTITY, Collections.emptyList()); case JSON_PATH: return new Query(query.path(), QueryType.JSON_PATH, query.expressions()); } throw new Error(); }
@Override int weigh(Entry<?> value) { int weight = 0; weight += query.path().length(); for (String e : query.expressions()) { weight += e.length(); } if (value != null && value.hasContent()) { weight += value.contentAsText().length(); } return weight; }
@Override int weigh(Change<?> value) { int weight = 0; weight += query.path().length(); for (String e : query.expressions()) { weight += e.length(); } weight += value.path().length(); final String content = value.contentAsText(); if (content != null) { weight += content.length(); } return weight; }
@Override int weigh(Entry<?> value) { int weight = 0; weight += query.path().length(); for (String e : query.expressions()) { weight += e.length(); } if (value != null && value.hasContent()) { weight += value.contentAsText().length(); } return weight; }
@Override int weigh(Entry<?> value) { int weight = 0; weight += query.path().length(); for (String e : query.expressions()) { weight += e.length(); } if (value != null && value.hasContent()) { weight += value.contentAsText().length(); } return weight; }
@Override int weigh(Change<?> value) { int weight = 0; weight += query.path().length(); for (String e : query.expressions()) { weight += e.length(); } weight += value.path().length(); final String content = value.contentAsText(); if (content != null) { weight += content.length(); } return weight; }
/** * Performs the specified {@link Query}. * * @throws EntryNotFoundException if there's no entry at the path specified in the {@link Query} * * @see #getOrNull(Revision, Query) */ default <T> CompletableFuture<Entry<T>> get(Revision revision, Query<T> query) { return getOrNull(revision, query).thenApply(res -> { if (res == null) { throw new EntryNotFoundException(revision, query.path()); } return res; }); }
@Override int weigh(Change<?> value) { int weight = 0; weight += query.path().length(); for (String e : query.expressions()) { weight += e.length(); } weight += value.path().length(); final String content = value.contentAsText(); if (content != null) { weight += content.length(); } return weight; }
/** * Performs the specified {@link Query}. * * @throws EntryNotFoundException if there's no entry at the path specified in the {@link Query} * * @see #getOrNull(Revision, Query) */ default <T> CompletableFuture<Entry<T>> get(Revision revision, Query<T> query) { return getOrNull(revision, query).thenApply(res -> { if (res == null) { throw new EntryNotFoundException(revision, query.path()); } return res; }); }
/** * Performs the specified {@link Query}. * * @throws EntryNotFoundException if there's no entry at the path specified in the {@link Query} * * @see #getOrNull(Revision, Query) */ default <T> CompletableFuture<Entry<T>> get(Revision revision, Query<T> query) { return getOrNull(revision, query).thenApply(res -> { if (res == null) { throw new EntryNotFoundException(revision, query.path()); } return res; }); }
private static void watch(Repository repo, Query<Object> query, Revision lastKnownRev, @Nullable Entry<Object> oldResult, CompletableFuture<Entry<Object>> parentFuture) { final CompletableFuture<Revision> future = repo.watch(lastKnownRev, query.path()); parentFuture.whenComplete((res, cause) -> future.completeExceptionally(CANCELLATION_EXCEPTION)); future.thenCompose(newRev -> repo.getOrNull(newRev, query).thenAccept(newResult -> { if (newResult == null || oldResult != null && Objects.equals(oldResult.content(), newResult.content())) { // Entry does not exist or did not change; watch again for more changes. if (!parentFuture.isDone()) { // ... only when the parent future has not been cancelled. watch(repo, query, newRev, oldResult, parentFuture); } } else { parentFuture.complete(newResult); } })).exceptionally(voidFunction(parentFuture::completeExceptionally)); }
private static CompletableFuture<Object> handleWatchFileSuccess( Repository repository, Query<?> query, Entry<?> entry) { final Revision revision = entry.revision(); final EntryDto<?> entryDto = convert(repository, entry); return repository.history(revision, revision, query.path()) .thenApply(commits -> { // The size of 'commits' should be 1. return convert(commits.get(0), entryDto); }); }
@Test public void convertIdentityQuery() throws Exception { final ServiceRequestContext ctx = mock(ServiceRequestContext.class); final String filePath = "/a.txt"; when(ctx.pathParam("path")).thenReturn(filePath); final Optional<Query<?>> query = convert(ctx); assert query.isPresent(); assertThat(query.get().type()).isSameAs(QueryType.IDENTITY); assertThat(query.get().path()).isEqualTo(filePath); }
@Test public void convertJsonPathQuery() throws Exception { final ServiceRequestContext ctx = mock(ServiceRequestContext.class); final String jsonFilePath = "/a.json"; when(ctx.pathParam("path")).thenReturn(jsonFilePath); final String httpQuery = "?jsonpath=%22%24.a%22"; // "$.a" when(ctx.query()).thenReturn(httpQuery); final Optional<Query<?>> query = convert(ctx); assert query.isPresent(); assertThat(query.get().type()).isSameAs(QueryType.JSON_PATH); assertThat(query.get().path()).isEqualTo(jsonFilePath); assertThat(query.get().expressions().get(0)).isEqualTo("\"$.a\""); }
@Test public void withoutExpression() throws Exception { final ServiceRequestContext ctx = mock(ServiceRequestContext.class); // even though the file is a JSON file, the converted query's type will be IDENTITY because there's no // expression final String jsonFilePath = "/a.json"; when(ctx.pathParam("path")).thenReturn(jsonFilePath); when(ctx.query()).thenReturn(""); final Optional<Query<?>> query = convert(ctx); assert query.isPresent(); assertThat(query.get().type()).isSameAs(QueryType.IDENTITY); assertThat(query.get().path()).isEqualTo(jsonFilePath); }
@Test @SuppressWarnings("unchecked") public void jsonPathQuery() throws JsonParseException { final Repository repo = setMockNames(newCachingRepo()); final Query<JsonNode> query = Query.ofJsonPath("/baz.json", "$.a"); final Entry<JsonNode> queryResult = Entry.ofJson(new Revision(10), query.path(), "{\"a\": \"b\"}"); doReturn(new Revision(10)).when(delegateRepo).normalizeNow(new Revision(10)); doReturn(new Revision(10)).when(delegateRepo).normalizeNow(HEAD); // Uncached when(delegateRepo.getOrNull(any(), any(Query.class))).thenReturn(completedFuture(queryResult)); assertThat(repo.get(HEAD, query).join()).isEqualTo(queryResult); verify(delegateRepo).getOrNull(new Revision(10), query); verifyNoMoreInteractions(delegateRepo); // Cached clearInvocations(delegateRepo); assertThat(repo.get(HEAD, query).join()).isEqualTo(queryResult); assertThat(repo.get(new Revision(10), query).join()).isEqualTo(queryResult); verify(delegateRepo, never()).getOrNull(any(), any(Query.class)); verifyNoMoreInteractions(delegateRepo); }