blob: a48e17ff996c3200bc11297914344d3be84adf25 [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.internal.rest;
import static org.apache.geode.test.util.ResourceUtils.createTempFileFromResource;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.test.compiler.JarBuilder;
import org.apache.geode.test.junit.rules.gfsh.GfshExecution;
import org.apache.geode.test.junit.rules.gfsh.GfshRule;
import org.apache.geode.test.junit.rules.gfsh.GfshScript;
import org.apache.geode.test.junit.rules.gfsh.internal.ProcessLogger;
import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactory;
@RunWith(Parameterized.class)
@UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class)
public class StandaloneClientManagementAPIAcceptanceTest {
@Rule
public GfshRule gfsh = new GfshRule();
@Rule
public TemporaryFolder tempDir = new TemporaryFolder();
private static String trustStorePath;
@Parameter
public Boolean useSsl;
@Parameters
public static Collection<Boolean> data() {
return Arrays.asList(true, false);
}
@BeforeClass
public static void beforeClass() {
/*
* This file was generated with:
* keytool -genkey -dname "CN=localhost" -alias self -validity 3650 -keyalg EC \
* -keystore trusted.keystore -keypass password -storepass password \
* -ext san=ip:127.0.0.1,dns:localhost -storetype jks
*/
trustStorePath =
createTempFileFromResource(StandaloneClientManagementAPIAcceptanceTest.class,
"/ssl/trusted.keystore").getAbsolutePath();
assertThat(trustStorePath).as("java file resource not found").isNotBlank();
}
@Test
public void clientCreatesRegionUsingClusterManagementService() throws Exception {
JarBuilder jarBuilder = new JarBuilder();
String filePath =
createTempFileFromResource(this.getClass(), "/ManagementClientCreateRegion.java")
.getAbsolutePath();
assertThat(filePath).as("java file resource not found").isNotBlank();
File outputJar = new File(tempDir.getRoot(), "output.jar");
jarBuilder.buildJar(outputJar, new File(filePath));
int[] availablePorts = AvailablePortHelper.getRandomAvailableTCPPorts(2);
int locatorPort = availablePorts[0];
int httpPort = availablePorts[1];
GfshExecution startCluster =
GfshScript.of(String.format("start locator --port=%d --J=-Dgemfire.http-service-port=%d %s",
locatorPort,
httpPort,
getSslParameters()),
String.format("start server --locators=localhost[%d] --server-port=0", locatorPort))
.withName("startCluster").execute(gfsh);
assertThat(startCluster.getProcess().exitValue())
.as("Cluster did not start correctly").isEqualTo(0);
Process process = launchClientProcess(outputJar, httpPort);
boolean exited = process.waitFor(30, TimeUnit.SECONDS);
assertThat(exited).as("Process did not exit within 10 seconds").isTrue();
assertThat(process.exitValue()).as("Process did not exit with 0 return code").isEqualTo(0);
GfshExecution listRegionsResult = GfshScript
.of(String.format("connect --locator=localhost[%d]", locatorPort), "list regions")
.withName("listRegions").execute(gfsh);
assertThat(listRegionsResult.getOutputText()).contains("REGION1");
}
private Process launchClientProcess(File outputJar, int httpPort) throws IOException {
Path javaBin = Paths.get(System.getProperty("java.home"), "bin", "java");
ProcessBuilder pBuilder = new ProcessBuilder();
pBuilder.directory(tempDir.newFolder());
StringBuilder classPath = new StringBuilder();
for (String module : Arrays.asList(
"commons-logging",
"commons-lang3",
"geode-common",
"geode-management",
"jackson-annotations",
"jackson-core",
"jackson-databind",
"httpclient",
"httpcore",
"spring-beans",
"spring-core",
"spring-web")) {
classPath.append(getJarOrClassesForModule(module));
classPath.append(File.pathSeparator);
}
classPath.append(File.pathSeparator);
classPath.append(outputJar.getAbsolutePath());
List<String> command = new ArrayList<>();
command.add(javaBin.toString());
if (useSsl) {
command.add("-Djavax.net.ssl.keyStore=" + trustStorePath);
command.add("-Djavax.net.ssl.keyStorePassword=password");
command.add("-Djavax.net.ssl.trustStore=" + trustStorePath);
command.add("-Djavax.net.ssl.trustStorePassword=password");
}
command.add("-classpath");
command.add(classPath.toString());
command.add("ManagementClientCreateRegion");
command.add("REGION1");
command.add(useSsl.toString());
command.add("" + httpPort);
pBuilder.command(command);
System.out.format("Launching client command: %s\n", command);
Process process = pBuilder.start();
new ProcessLogger(process, "clientCreateRegion");
return process;
}
private String getSslParameters() {
if (useSsl) {
return String.format(" --J=-Dgemfire.ssl-keystore=%1$s"
+ " --J=-Dgemfire.ssl-keystore-password=%2$s"
+ " --J=-Dgemfire.ssl-truststore=%1$s"
+ " --J=-Dgemfire.ssl-truststore-password=%2$s"
+ " --J=-Dgemfire.ssl-enabled-components=web",
trustStorePath, "password");
}
return "";
}
private String getJarOrClassesForModule(String module) {
String classPath = Arrays.stream(System.getProperty("java.class.path")
.split(File.pathSeparator))
.filter(x -> x.contains(module)
&& (x.endsWith("/classes") || x.endsWith("/classes/java/main")
|| x.endsWith("/resources") || x.endsWith("/resources/main")
|| x.endsWith(".jar")))
.collect(Collectors.joining(File.pathSeparator));
assertThat(classPath).as("no classes found for module: " + module)
.isNotBlank();
return classPath;
}
}