Ensure that all actuator endpoint accessors work for Boot 2.0
This commit is contained in:
@@ -26,6 +26,8 @@ import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -292,10 +294,33 @@ public class SpringBootApp {
|
||||
if (environment != null) {
|
||||
JSONObject env = new JSONObject(environment);
|
||||
if (env != null) {
|
||||
JSONObject portsObject = env.getJSONObject("server.ports");
|
||||
JSONObject portsObject = env.optJSONObject("server.ports");
|
||||
if (portsObject != null) {
|
||||
String portValue = portsObject.get("local.server.port").toString();
|
||||
return portValue;
|
||||
String portValue = portsObject.optString("local.server.port");
|
||||
if (portValue!=null) {
|
||||
return portValue;
|
||||
}
|
||||
}
|
||||
//Not found as direct property value... in Boot 2.0 we must look inside the 'propertySources'.
|
||||
//Similar... but structure is more complex.
|
||||
JSONArray propertySources = env.optJSONArray("propertySources");
|
||||
if (propertySources!=null) {
|
||||
for (Object _source : propertySources) {
|
||||
if (_source instanceof JSONObject) {
|
||||
JSONObject source = (JSONObject) _source;
|
||||
String sourceName = source.optString("name");
|
||||
if ("server.ports".equals(sourceName)) {
|
||||
JSONObject props = source.optJSONObject("properties");
|
||||
JSONObject valueObject = props.optJSONObject("local.server.port");
|
||||
if (valueObject!=null) {
|
||||
String portValue = valueObject.optString("value");
|
||||
if (portValue!=null) {
|
||||
return portValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,7 +342,6 @@ public class SpringBootApp {
|
||||
}
|
||||
catch (InstanceNotFoundException e) {
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,42 +11,59 @@
|
||||
package org.springframework.ide.vscode.commons.boot.app.cli;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.json.JSONObject;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.commons.util.AsyncProcess;
|
||||
import org.springframework.ide.vscode.commons.util.ExternalCommand;
|
||||
import org.springframework.ide.vscode.commons.util.StringUtil;
|
||||
import org.springframework.ide.vscode.commons.util.test.ACondition;
|
||||
|
||||
public class SpringBootAppTest {
|
||||
|
||||
private static final String appName = "actuator-client-test-subject";
|
||||
// private static final String appName = "actuator-client-15-test-subject"; // Boot 1.5 test app
|
||||
private static final String appName = "actuator-client-20-test-subject"; //Boot 2.0 test app
|
||||
|
||||
private static final Duration TIMEOUT = Duration.ofSeconds(10);
|
||||
private static AsyncProcess testAppRunner;
|
||||
private static SpringBootApp testApp;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupClass() throws Exception {
|
||||
testAppRunner = startTestApplication(SpringBootAppTest.class.getResource("/"+appName+"-0.0.1-SNAPSHOT.jar"));
|
||||
|
||||
//TODO: add some wait here until the boot app is 'ready'. Otherwise some of our test will just fail trying to read stuff that's not there yet.
|
||||
testApp = getAppContaining(appName);
|
||||
assertNotNull(testApp);
|
||||
}
|
||||
|
||||
private static AsyncProcess startTestApplication(URL jarUrl) throws Exception {
|
||||
File jarFile = new File(jarUrl.toURI());
|
||||
return new AsyncProcess(new File("."), new ExternalCommand(
|
||||
"java",
|
||||
"-Dserver.port=0", //let spring boot pick randomized free port
|
||||
"-jar",
|
||||
jarFile.getAbsolutePath()
|
||||
));
|
||||
return new AsyncProcess(
|
||||
new File("."),
|
||||
new ExternalCommand(
|
||||
"java",
|
||||
"-Dserver.port=0", //let spring boot pick randomized free port
|
||||
"-jar",
|
||||
jarFile.getAbsolutePath()
|
||||
),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
private static SpringBootApp getAppContaining(String nameFragment) throws Exception {
|
||||
return SpringBootApp.getAllRunningJavaApps().values().stream().filter(app -> app.getProcessName().contains(nameFragment)).findAny().get();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() throws Exception {
|
||||
testAppRunner.kill();
|
||||
@@ -65,5 +82,64 @@ public class SpringBootAppTest {
|
||||
Optional<SpringBootApp> myProcess = allApps.values().stream().filter(app -> app.getProcessName().contains(appName)).findAny();
|
||||
assertTrue(myProcess.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPort() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
int port = Integer.parseInt(testApp.getPort());
|
||||
assertTrue(port > 0);
|
||||
System.out.println("port = "+port);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getHost() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
String host = testApp.getHost();
|
||||
assertTrue(StringUtil.hasText(host));
|
||||
System.out.println("host = "+host);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getEnvironment() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
String env = testApp.getEnvironment();
|
||||
assertNonEmptyJsonObject(env);
|
||||
System.out.println("env = "+env);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBeans() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
String beans = testApp.getBeans();
|
||||
assertNonEmptyJsonObject(beans);
|
||||
System.out.println("beans = "+beans);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestMappings() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
String result = testApp.getRequestMappings();
|
||||
assertNonEmptyJsonObject(result);
|
||||
System.out.println("requestMappings = "+result);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAutoConfigReport() throws Exception {
|
||||
ACondition.waitFor(TIMEOUT, () -> {
|
||||
String result = testApp.getAutoConfigReport();
|
||||
assertNonEmptyJsonObject(result);
|
||||
System.out.println("autoconfreport = "+result);
|
||||
});
|
||||
}
|
||||
|
||||
private void assertNonEmptyJsonObject(String jsonData) {
|
||||
JSONObject parsed = new JSONObject(jsonData);
|
||||
assertFalse(parsed.keySet().isEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Pivotal, Inc.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Pivotal, Inc. - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.springframework.ide.vscode.commons.util.test;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.ExceptionUtil;
|
||||
|
||||
/**
|
||||
* Utility for async condition checking, mostly intended for testing code.
|
||||
* <p>
|
||||
* Uses a polling loop to repeatedly evaluate some code that represents a condition
|
||||
* of some kind. The test passes as soon as the condition passes, or fails if
|
||||
* the condition does not pass within a given time limit.
|
||||
*/
|
||||
public class ACondition {
|
||||
|
||||
public interface Asserter {
|
||||
void doAsserts() throws Exception;
|
||||
}
|
||||
|
||||
public static void waitFor(Duration timeout, Asserter asserter) throws Exception {
|
||||
long startTime = System.currentTimeMillis();
|
||||
long timeout_millis = timeout.toMillis();
|
||||
Throwable lastException = null;
|
||||
do {
|
||||
try {
|
||||
asserter.doAsserts();
|
||||
return;
|
||||
} catch (Throwable e) {
|
||||
lastException = e;
|
||||
if (System.currentTimeMillis()-startTime < timeout_millis) {
|
||||
Thread.sleep(300);
|
||||
}
|
||||
}
|
||||
} while (System.currentTimeMillis()-startTime < timeout_millis);
|
||||
throw ExceptionUtil.exception(lastException);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user