private static Query<JsonNode> buildQuery(CentralDogmaBeanConfig config) { checkArgument(config.path().get().endsWith(".json"), "path: %s (expected: ends with '.json')", config.path().get()); return Query.ofJsonPath(config.path().get(), config.jsonPath().orElse("$")); } }
/** * Returns a newly-created {@link Query} that applies a series of expressions to the content. * * @param type the type of the {@link Query} * @param path the path of a file being queried on * @param expressions the expressions to apply */ static Query<?> of(QueryType type, String path, @Nullable String... expressions) { requireNonNull(type, "type"); switch (type) { case IDENTITY: return new IdentityQuery<>(path); case JSON_PATH: requireNonNull(expressions, "expressions"); return ofJsonPath(path, expressions); default: throw new IllegalArgumentException("Illegal query type: " + type.name()); } }
/** * Returns a newly-created {@link Query} that applies a series of expressions to the content. * * @param type the type of the {@link Query} * @param path the path of a file being queried on * @param expressions the expressions to apply */ static Query<?> of(QueryType type, String path, @Nullable String... expressions) { requireNonNull(type, "type"); switch (type) { case IDENTITY: return new IdentityQuery<>(path); case JSON_PATH: requireNonNull(expressions, "expressions"); return ofJsonPath(path, expressions); default: throw new IllegalArgumentException("Illegal query type: " + type.name()); } }
/** * Returns a newly-created {@link Query} that applies a series of expressions to the content. * * @param type the type of the {@link Query} * @param path the path of a file being queried on * @param expressions the expressions to apply */ static Query<?> of(QueryType type, String path, @Nullable String... expressions) { requireNonNull(type, "type"); switch (type) { case IDENTITY: return new IdentityQuery<>(path); case JSON_PATH: requireNonNull(expressions, "expressions"); return ofJsonPath(path, expressions); default: throw new IllegalArgumentException("Illegal query type: " + type.name()); } }
private static Query<JsonNode> buildQuery(CentralDogmaBeanConfig config) { checkArgument(config.path().get().endsWith(".json"), "path: %s (expected: ends with '.json')", config.path().get()); return Query.ofJsonPath(config.path().get(), config.jsonPath().orElse("$")); } }
/** * Converts the specified {@code request} to {@link Optional} which contains {@link Query} when * the request has a valid file path. {@link Optional#EMPTY} otherwise. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final String path = getPath(ctx); final Optional<Iterable<String>> jsonPaths = getJsonPaths(ctx); if (jsonPaths.isPresent()) { return Optional.of(Query.ofJsonPath(path, jsonPaths.get())); } if (isValidFilePath(path)) { return Optional.of(Query.of(QueryType.IDENTITY, path)); } return Optional.empty(); }
/** * Converts the specified {@code request} to {@link Optional} which contains {@link Query} when * the request has a valid file path. {@link Optional#EMPTY} otherwise. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final String path = getPath(ctx); final Optional<Iterable<String>> jsonPaths = getJsonPaths(ctx); if (jsonPaths.isPresent()) { return Optional.of(Query.ofJsonPath(path, jsonPaths.get())); } if (isValidFilePath(path)) { return Optional.of(Query.of(QueryType.IDENTITY, path)); } return Optional.empty(); }
private static Query<JsonNode> buildQuery(CentralDogmaBeanConfig config) { checkArgument(config.path().get().endsWith(".json"), "path: %s (expected: ends with '.json')", config.path().get()); return Query.ofJsonPath(config.path().get(), config.jsonPath().orElse("$")); } }
/** * Converts the specified {@code request} to {@link Optional} which contains {@link Query} when * the request has a valid file path. {@link Optional#EMPTY} otherwise. */ @Override public Object convertRequest(ServiceRequestContext ctx, AggregatedHttpMessage request, Class<?> expectedResultType) throws Exception { final String path = getPath(ctx); final Optional<Iterable<String>> jsonPaths = getJsonPaths(ctx); if (jsonPaths.isPresent()) { return Optional.of(Query.ofJsonPath(path, jsonPaths.get())); } if (isValidFilePath(path)) { return Optional.of(Query.of(QueryType.IDENTITY, path)); } return Optional.empty(); }
@Override protected com.linecorp.centraldogma.common.Query<?> doBackward(Query query) { switch (query.getType()) { case IDENTITY: return com.linecorp.centraldogma.common.Query.of( com.linecorp.centraldogma.common.QueryType.IDENTITY, query.getPath()); case JSON_PATH: return com.linecorp.centraldogma.common.Query.ofJsonPath(query.getPath(), query.getExpressions()); } throw new Error(); } }
@Override protected com.linecorp.centraldogma.common.Query<?> doBackward(Query query) { switch (query.getType()) { case IDENTITY: return com.linecorp.centraldogma.common.Query.of( com.linecorp.centraldogma.common.QueryType.IDENTITY, query.getPath()); case JSON_PATH: return com.linecorp.centraldogma.common.Query.ofJsonPath(query.getPath(), query.getExpressions()); } throw new Error(); } }
@Test public void testInvalidJsonPath() { assertThatThrownBy(() -> rule.client().getFile( rule.project(), rule.repo1(), Revision.HEAD, Query.ofJsonPath("/test/test2.json", "$.non_exist_path")).join()) .isInstanceOf(CompletionException.class).hasCauseInstanceOf(QueryExecutionException.class); }
@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); }
@Test @SuppressWarnings("unchecked") public void jsonPathQueryMissingEntry() { final Repository repo = setMockNames(newCachingRepo()); final Query<JsonNode> query = Query.ofJsonPath("/baz.json", "$.a"); 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(null)); assertThat(repo.getOrNull(HEAD, query).join()).isNull(); verify(delegateRepo).getOrNull(new Revision(10), query); verifyNoMoreInteractions(delegateRepo); // Cached clearInvocations(delegateRepo); assertThat(repo.getOrNull(HEAD, query).join()).isNull(); assertThat(repo.getOrNull(new Revision(10), query).join()).isNull(); verify(delegateRepo, never()).getOrNull(any(), any(Query.class)); verifyNoMoreInteractions(delegateRepo); }
@Test public void testInvalidRepo() throws Exception { assertThatThrownByWithExpectedException(RepositoryNotFoundException.class, "non_exist_repo", () -> rule.client().getFile(rule.project(), "non_exist_repo", Revision.HEAD, Query.ofJsonPath("/test/test2.json", "$.a")).join()) .isInstanceOf(CompletionException.class).hasCauseInstanceOf(RepositoryNotFoundException.class); }
@Test public void testInvalidProject() throws Exception { assertThatThrownByWithExpectedException(ProjectNotFoundException.class, "non_exist_proj", () -> rule.client().getFile("non_exist_proj", rule.repo1(), Revision.HEAD, Query.ofJsonPath("/test/test2.json", "$.non_exist_path")).join()) .isInstanceOf(CompletionException.class).hasCauseInstanceOf(ProjectNotFoundException.class); } }
@Test public void testWatchFileWithTimeout() { final Entry<JsonNode> res = rule.client().watchFile( rule.project(), rule.repo1(), Revision.HEAD, Query.ofJsonPath("/test/test1.json", "$"), 1000).join(); assertThat(res).isNull(); } }
@Test public void testInvalidFile() throws Exception { assertThatThrownByWithExpectedException(EntryNotFoundException.class, "non_existing_file", () -> rule.client().getFile(rule.project(), rule.repo1(), Revision.HEAD, Query.ofJsonPath("/test/non_existing_file.json", "$.a")).join()) .isInstanceOf(CompletionException.class).hasCauseInstanceOf(EntryNotFoundException.class); }
@Test public void testJsonConversion() { TestUtil.assertJsonConversion(Query.ofText("/foo.txt"), Query.class, '{' + " \"type\": \"IDENTITY\"," + " \"path\": \"/foo.txt\"" + '}'); TestUtil.assertJsonConversion(Query.ofJsonPath("/bar.json", "$..author", "$..name"), Query.class, '{' + " \"type\": \"JSON_PATH\"," + " \"path\": \"/bar.json\"," + " \"expressions\": [ \"$..author\", \"$..name\" ]" + '}'); } }
@Test public void testQueryByRange() throws Exception { final String path = "/test_json_file.json"; for (int i = 0; i < 5; i++) { final Change<JsonNode> change = Change.ofJsonUpsert(path, String.format("{ \"key\" : \"%d\"}", i)); rule.client().push( rule.project(), rule.repo1(), HEAD, TestConstants.randomText(), change).join(); } final Change<JsonNode> res = rule.client().getDiff( rule.project(), rule.repo1(), new Revision(-4), new Revision(-1), Query.ofJsonPath(path, "$.key")).join(); assertThat(res.type()).isEqualTo(ChangeType.APPLY_JSON_PATCH); assertThatJson(res.content()).isEqualTo( "[{" + " \"op\": \"safeReplace\"," + " \"path\": \"\"," + " \"oldValue\": \"1\"," + " \"value\": \"4\"" + "}]"); }