blob: 9c4f971fbe4b6a5ad414716a1e4db571e82eb1ea [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.management;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import com.arakelian.jq.ImmutableJqLibrary;
import com.arakelian.jq.ImmutableJqRequest;
import com.arakelian.jq.JqLibrary;
import com.arakelian.jq.JqRequest;
import com.arakelian.jq.JqResponse;
import com.fasterxml.jackson.databind.JsonNode;
import org.assertj.core.api.Assertions;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.apache.geode.cache.configuration.RegionConfig;
import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.lang.Identifiable;
import org.apache.geode.management.api.ClusterManagementService;
import org.apache.geode.management.client.ClusterManagementServiceBuilder;
import org.apache.geode.management.configuration.Region;
import org.apache.geode.management.configuration.RegionType;
import org.apache.geode.test.dunit.rules.ClusterStartupRule;
import org.apache.geode.test.dunit.rules.MemberVM;
import org.apache.geode.test.junit.rules.GeodeDevRestClient;
import org.apache.geode.test.junit.rules.RequiresGeodeHome;
/**
* this test is to make sure:
* 1. we have a test to verify the jq filter we add to the controller
* 2. the JQFilter we added is valid
*/
public class JQFilterVerificationDUnitTest {
@ClassRule
public static ClusterStartupRule cluster = new ClusterStartupRule();
private static MemberVM locator, server;
private static ClusterManagementService cms;
@ClassRule
public static RequiresGeodeHome requiresGeodeHome = new RequiresGeodeHome();
private static GeodeDevRestClient client;
private static Map<String, JsonNode> apiWithJQFilters = new HashMap<>();
private static JqLibrary library;
@BeforeClass
public static void beforeClass() throws IOException {
locator = cluster.startLocatorVM(0, l -> l.withHttpService());
server = cluster.startServerVM(1, locator.getPort());
cms = ClusterManagementServiceBuilder.buildWithHostAddress()
.setHostAddress("localhost", locator.getHttpPort()).build();
Region region = new Region();
region.setName("regionA");
region.setType(RegionType.REPLICATE);
cms.create(region);
// create an index using CPS api since CMS doesn't support creating index yet
locator.invoke(() -> {
InternalConfigurationPersistenceService cps =
ClusterStartupRule.getLocator().getConfigurationPersistenceService();
cps.updateCacheConfig("cluster", cc -> {
RegionConfig regionA = Identifiable.find(cc.getRegions(), "regionA");
RegionConfig.Index index = new RegionConfig.Index();
index.setName("index1");
index.setFromClause("regionA");
index.setExpression("id");
regionA.getIndexes().add(index);
return cc;
});
});
client = new GeodeDevRestClient("/management", "localhost", locator.getHttpPort(), false);
JsonNode jsonObject =
client.doGetAndAssert("/v1/api-docs").getJsonObject().get("paths");
Iterator<Map.Entry<String, JsonNode>> urls = jsonObject.fields();
while (urls.hasNext()) {
Map.Entry<String, JsonNode> url = urls.next();
Iterator<Map.Entry<String, JsonNode>> methods = url.getValue().fields();
while (methods.hasNext()) {
Map.Entry<String, JsonNode> method = methods.next();
// gather all the rest endpoint that has jqFilter defined.
if (method.getValue().get("jqFilter") != null) {
apiWithJQFilters.put(url.getKey(), method.getValue());
}
}
}
library = ImmutableJqLibrary.of();
}
@AfterClass
public static void afterClass() throws Exception {
// after all the tests are done, the map has nothing left.
assertThat(apiWithJQFilters).hasSize(0);
}
@Test
public void getMembers() throws IOException {
String uri = "/v1/members";
JqResponse response =
getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"locator-0\"");
}
@Test
public void getMember() throws Exception {
String uri = "/v1/members/locator-0";
JqResponse response = getJqResponse(uri,
apiWithJQFilters.remove("/v1/members/{id}").get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"locator-0\"");
}
@Test
public void listRegions() throws Exception {
String uri = "/v1/regions";
JqResponse response =
getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"regionA\"");
}
JqResponse getJqResponse(String uri, String jqFilter) throws IOException {
JsonNode jsonObject = client.doGetAndAssert(uri).getJsonObject();
final JqRequest request = ImmutableJqRequest.builder()
.lib(library).input(jsonObject.toString()).filter(jqFilter).build();
return request.execute();
}
@Test
public void getRegion() throws Exception {
String uri = "/v1/regions/regionA";
JqResponse response = getJqResponse(uri,
apiWithJQFilters.remove("/v1/regions/{id}").get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"regionA\"");
}
@Test
public void listIndex() throws Exception {
String uri = "/v1/indexes";
JqResponse response =
getJqResponse(uri, apiWithJQFilters.remove(uri).get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"index1\"");
}
@Test
public void listRegionIndex() throws Exception {
String uri = "/v1/regions/regionA/indexes";
JqResponse response = getJqResponse(uri, apiWithJQFilters
.remove("/v1/regions/{regionName}/indexes").get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"index1\"");
}
@Test
public void getIndex() throws Exception {
String uri = "/v1/regions/regionA/indexes/index1";
JqResponse response = getJqResponse(uri, apiWithJQFilters
.remove("/v1/regions/{regionName}/indexes/{id}").get("jqFilter").textValue());
Assertions.assertThat(response.hasErrors()).isFalse();
System.out.println("JQ output: " + response.getOutput());
Assertions.assertThat(response.getOutput()).contains("\"name\": \"index1\"");
}
}