Skip to content

Commit

Permalink
Autofill homePageUrl and statusPageUrl of an InstanceInfo in Eu…
Browse files Browse the repository at this point in the history
…reka using path properties. (line#5465)

Motivation:
Following up on the improvements introduced in
line#5369, it's beneficial to extend the
autofill feature to include `homePageUrl` and `statusPageUrl` of an
`InstanceInfo`. This enhancement streamlines configuration by
automatically populating these URLs based on corresponding path
properties.

Modifications:
- Introduce `homePageUrlPath` and `statusPageUrlPath` properties to
`InstanceInfo` and their respective builders.
- Implement autofill functionality for `homePageUrl` and `statusPageUrl`
using the configured path properties.

Result:
- `homePageUrl` and `statusPageUrl` of an `InstanceInfo` in Eureka are
correctly set if corresponding path properties are configured.
- Close line#5464
  • Loading branch information
minwoox authored and jrhee17 committed Mar 4, 2024
1 parent c0d4eea commit 51a76ad
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;
Expand All @@ -36,7 +37,7 @@
/**
* An instance information.
*/
@JsonIgnoreProperties(value = { "healthCheckUrlPath" }, ignoreUnknown = true)
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonRootName("instance")
public final class InstanceInfo {

Expand All @@ -61,9 +62,13 @@ public final class InstanceInfo {
private final PortWrapper securePort;
private final InstanceStatus status;

@Nullable
private final String homePageUrlPath;
@Nullable
private final String homePageUrl;
@Nullable
private final String statusPageUrlPath;
@Nullable
private final String statusPageUrl;
@Nullable
private final String healthCheckUrlPath;
Expand Down Expand Up @@ -99,7 +104,7 @@ public InstanceInfo(@Nullable @JsonProperty("instanceId") String instanceId,
@JsonProperty("leaseInfo") LeaseInfo leaseInfo,
@Nullable @JsonProperty("metadata") Map<String, String> metadata) {
this(instanceId, appName, appGroupName, hostName, ipAddr, vipAddress, secureVipAddress, port,
securePort, status, homePageUrl, statusPageUrl, null, healthCheckUrl,
securePort, status, null, homePageUrl, null, statusPageUrl, null, healthCheckUrl,
secureHealthCheckUrl, dataCenterInfo, leaseInfo, metadata);
}

Expand All @@ -116,7 +121,9 @@ public InstanceInfo(@Nullable String instanceId,
PortWrapper port,
PortWrapper securePort,
InstanceStatus status,
@Nullable String homePageUrlPath, // Not in JSON
@Nullable String homePageUrl,
@Nullable String statusPageUrlPath, // Not in JSON
@Nullable String statusPageUrl,
@Nullable String healthCheckUrlPath, // Not in JSON
@Nullable String healthCheckUrl,
Expand All @@ -134,7 +141,9 @@ public InstanceInfo(@Nullable String instanceId,
this.port = requireNonNull(port, "port");
this.securePort = requireNonNull(securePort, "securePort");
this.status = requireNonNull(status, "status");
this.homePageUrlPath = homePageUrlPath;
this.homePageUrl = homePageUrl;
this.statusPageUrlPath = statusPageUrlPath;
this.statusPageUrl = statusPageUrl;
this.healthCheckUrlPath = healthCheckUrlPath;
this.healthCheckUrl = healthCheckUrl;
Expand Down Expand Up @@ -229,6 +238,17 @@ public InstanceStatus getStatus() {
return status;
}

/**
* Returns the home page URL path of this instance.
*
* <p>When set, {@link #getHomePageUrl()} will be built with {@link #getHostName()} and {@link #getPort()}.
*/
@Nullable
@JsonIgnore
public String getHomePageUrlPath() {
return homePageUrlPath;
}

/**
* Returns the home page URL of this instance.
*/
Expand All @@ -237,6 +257,18 @@ public String getHomePageUrl() {
return homePageUrl;
}

/**
* Returns the status page URL path of this instance.
*
* <p>When set, {@link #getStatusPageUrl()} will be built with {@link #getHostName()} and
* {@link #getPort()}.
*/
@Nullable
@JsonIgnore
public String getStatusPageUrlPath() {
return statusPageUrlPath;
}

/**
* Returns the status page URL of this instance.
*/
Expand All @@ -252,6 +284,7 @@ public String getStatusPageUrl() {
* {@link #getPort()} or {@link #getSecurePort()} for {@link #getSecureHealthCheckUrl()}.
*/
@Nullable
@JsonIgnore
public String getHealthCheckUrlPath() {
return healthCheckUrlPath;
}
Expand Down Expand Up @@ -327,7 +360,9 @@ public boolean equals(Object o) {
Objects.equal(port, that.port) &&
Objects.equal(securePort, that.securePort) &&
status == that.status &&
Objects.equal(homePageUrlPath, that.homePageUrlPath) &&
Objects.equal(homePageUrl, that.homePageUrl) &&
Objects.equal(statusPageUrlPath, that.statusPageUrlPath) &&
Objects.equal(statusPageUrl, that.statusPageUrl) &&
Objects.equal(healthCheckUrlPath, that.healthCheckUrlPath) &&
Objects.equal(healthCheckUrl, that.healthCheckUrl) &&
Expand All @@ -341,7 +376,8 @@ public boolean equals(Object o) {
public int hashCode() {
return Objects.hashCode(instanceId, hostName, appName, appGroupName, ipAddr, vipAddress,
secureVipAddress, port, securePort, status,
homePageUrl, statusPageUrl, healthCheckUrlPath, healthCheckUrl,
homePageUrlPath, homePageUrl, statusPageUrlPath, statusPageUrl,
healthCheckUrlPath, healthCheckUrl,
secureHealthCheckUrl, dataCenterInfo, leaseInfo, metadata);
}

Expand All @@ -358,7 +394,9 @@ public String toString() {
.add("port", port)
.add("securePort", securePort)
.add("status", status)
.add("homePageUrlPath", homePageUrlPath)
.add("homePageUrl", homePageUrl)
.add("statusPageUrlPath", statusPageUrlPath)
.add("statusPageUrl", statusPageUrl)
.add("healthCheckUrlPath", healthCheckUrlPath)
.add("healthCheckUrl", healthCheckUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.linecorp.armeria.server.eureka;

import static com.google.common.base.Strings.isNullOrEmpty;
import static com.linecorp.armeria.server.eureka.InstanceInfoBuilder.disabledPort;
import static java.util.Objects.requireNonNull;

Expand Down Expand Up @@ -225,6 +226,11 @@ private static InstanceInfo fillAndCreateNewInfo(InstanceInfo oldInfo, Server se
} else {
hostnameOrIpAddr = hostName;
}

final String homePageUrl = pageUrl(hostnameOrIpAddr, oldInfo.getHomePageUrlPath(),
oldInfo.getHomePageUrl(), portWrapper);
final String statusPageUrl = pageUrl(hostnameOrIpAddr, oldInfo.getStatusPageUrlPath(),
oldInfo.getStatusPageUrl(), portWrapper);
final String healthCheckUrl = healthCheckUrl(hostnameOrIpAddr, oldInfo.getHealthCheckUrlPath(),
oldInfo.getHealthCheckUrl(), portWrapper,
healthCheckService, SessionProtocol.HTTP);
Expand All @@ -235,7 +241,7 @@ private static InstanceInfo fillAndCreateNewInfo(InstanceInfo oldInfo, Server se

return new InstanceInfo(instanceId, appName, oldInfo.getAppGroupName(), hostName, ipAddr,
vipAddress, secureVipAddress, portWrapper, securePortWrapper, InstanceStatus.UP,
oldInfo.getHomePageUrl(), oldInfo.getStatusPageUrl(), healthCheckUrl,
homePageUrl, statusPageUrl, healthCheckUrl,
secureHealthCheckUrl, oldInfo.getDataCenterInfo(),
oldInfo.getLeaseInfo(), oldInfo.getMetadata());
}
Expand Down Expand Up @@ -269,23 +275,43 @@ private static String vipAddress(@Nullable String vipAddress, String hostName, P
return vipAddress != null ? vipAddress : hostName;
}

@Nullable
private static String pageUrl(String hostnameOrIpAddr, @Nullable String pageUrlPath,
@Nullable String pageUrl, PortWrapper portWrapper) {
if (!isNullOrEmpty(pageUrl)) {
return pageUrl;
}
if (pageUrlPath == null || !portWrapper.isEnabled()) { // allow an empty String.
return null;
}
return concatPath(baseUrl(hostnameOrIpAddr, portWrapper, SessionProtocol.HTTP), pageUrlPath);
}

private static String baseUrl(String hostnameOrIpAddr, PortWrapper portWrapper,
SessionProtocol sessionProtocol) {
return sessionProtocol.uriText() + "://" +
hostnameOrIpAddr(hostnameOrIpAddr) + ':' + portWrapper.getPort();
}

private static String concatPath(String baseURL, String path) {
return !path.isEmpty() && path.charAt(0) == '/' ? baseURL + path : baseURL + '/' + path;
}

@Nullable
private static String healthCheckUrl(String hostnameOrIpAddr, @Nullable String oldHealthCheckUrlPath,
@Nullable String oldHealthCheckUrl,
PortWrapper portWrapper,
Optional<ServiceConfig> healthCheckService,
SessionProtocol sessionProtocol) {
if (oldHealthCheckUrl != null) {
if (!isNullOrEmpty(oldHealthCheckUrl)) {
return oldHealthCheckUrl;
}
if (!portWrapper.isEnabled() || !healthCheckService.isPresent()) {
return null;
}
final String baseURL = sessionProtocol.uriText() + "://" +
hostnameOrIpAddr(hostnameOrIpAddr) + ':' + portWrapper.getPort();
if (oldHealthCheckUrlPath != null) {
return !oldHealthCheckUrlPath.isEmpty() && oldHealthCheckUrlPath.charAt(0) == '/' ?
baseURL + oldHealthCheckUrlPath : baseURL + '/' + oldHealthCheckUrlPath;
final String baseURL = baseUrl(hostnameOrIpAddr, portWrapper, sessionProtocol);
if (oldHealthCheckUrlPath != null) { // allow an empty String
return concatPath(baseURL, oldHealthCheckUrlPath);
}
final ServiceConfig healthCheckServiceConfig = healthCheckService.get();
final Route route = healthCheckServiceConfig.route();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,6 +286,14 @@ public EurekaUpdatingListenerBuilder secureVipAddress(String secureVipAddress) {
return this;
}

/**
* Sets the home page URL path used to automatically create {@link #homePageUrl(String)}.
*/
public EurekaUpdatingListenerBuilder homePageUrlPath(String homePageUrlPath) {
instanceInfoBuilder.homePageUrlPath(homePageUrlPath);
return this;
}

/**
* Sets the home page URL.
*/
Expand All @@ -294,6 +302,14 @@ public EurekaUpdatingListenerBuilder homePageUrl(String homePageUrl) {
return this;
}

/**
* Sets the status page URL path used to automatically create {@link #statusPageUrl(String)}.
*/
public EurekaUpdatingListenerBuilder statusPageUrlPath(String statusPageUrlPath) {
instanceInfoBuilder.statusPageUrlPath(statusPageUrlPath);
return this;
}

/**
* Sets the status page URL.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,12 @@ final class InstanceInfoBuilder {
@Nullable
private String secureVipAddress;
@Nullable
private String homePageUrlPath;
@Nullable
private String homePageUrl;
@Nullable
private String statusPageUrlPath;
@Nullable
private String statusPageUrl;
@Nullable
private String healthCheckUrlPath;
Expand Down Expand Up @@ -180,6 +184,14 @@ InstanceInfoBuilder secureVipAddress(String secureVipAddress) {
return this;
}

/**
* Sets the home page URL path.
*/
InstanceInfoBuilder homePageUrlPath(String homePageUrlPath) {
this.homePageUrlPath = requireNonNull(homePageUrlPath, "homePageUrlPath");
return this;
}

/**
* Sets the home page URL.
*/
Expand All @@ -188,6 +200,14 @@ InstanceInfoBuilder homePageUrl(String homePageUrl) {
return this;
}

/**
* Sets the status page URL path.
*/
InstanceInfoBuilder statusPageUrlPath(String statusPageUrlPath) {
this.statusPageUrlPath = requireNonNull(statusPageUrlPath, "statusPageUrlPath");
return this;
}

/**
* Sets the status page URL.
*/
Expand Down Expand Up @@ -251,8 +271,8 @@ InstanceInfo build() {
final LeaseInfo leaseInfo = new LeaseInfo(renewalIntervalSeconds, leaseDurationSeconds);
return new InstanceInfo(instanceId, appName, appGroupName, hostname, ipAddr, vipAddress,
secureVipAddress, port, securePort, InstanceStatus.UP,
homePageUrl, statusPageUrl, healthCheckUrlPath, healthCheckUrl,
secureHealthCheckUrl,
homePageUrlPath, homePageUrl, statusPageUrlPath, statusPageUrl,
healthCheckUrlPath, healthCheckUrl, secureHealthCheckUrl,
new DataCenterInfo(dataCenterName, dataCenterMetadata), leaseInfo,
metadata);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,18 +256,22 @@ void defaultInstanceId() throws IOException {
}

@ParameterizedTest
@CsvSource(value = {
"'',/",
"custom-health,/custom-health",
"/custom-health,/custom-health",
@CsvSource({
"'',/,'',/,'',/",
"custom-health,/custom-health,home-page,/home-page,status-page,/status-page",
"/custom-health,/custom-health,/home-page,/home-page,/status-page,/status-page",
})
void customHealthCheckPath(String healthCheckUrlPath, String expectedHealthCheckUrlPath)
void customPaths(String healthCheckUrlPath, String expectedHealthCheckUrlPath,
String homePageUrlPath, String expectedHomePageUrlPath,
String statusPageUrlPath, String expectedStatusPageUrlPath)
throws IOException {
final EurekaUpdatingListener listener =
EurekaUpdatingListener.builder(eurekaServer.httpUri())
.renewalInterval(Duration.ofSeconds(2))
.leaseDuration(Duration.ofSeconds(10))
.hostname("myhost")
.homePageUrlPath(homePageUrlPath)
.statusPageUrlPath(statusPageUrlPath)
.healthCheckUrlPath(healthCheckUrlPath)
.port(88)
.securePort(8888)
Expand All @@ -285,8 +289,9 @@ void customHealthCheckPath(String healthCheckUrlPath, String expectedHealthCheck
await().until(() -> registerContentCaptor.get() != null);
final InstanceInfo instanceInfo = mapper.readValue(registerContentCaptor.get().array(),
InstanceInfo.class);
assertThat(instanceInfo.getHealthCheckUrl())
.isEqualTo("http://myhost:88" + expectedHealthCheckUrlPath);
assertThat(instanceInfo.getHomePageUrl()).isEqualTo("http://myhost:88" + expectedHomePageUrlPath);
assertThat(instanceInfo.getStatusPageUrl()).isEqualTo("http://myhost:88" + expectedStatusPageUrlPath);
assertThat(instanceInfo.getHealthCheckUrl()).isEqualTo("http://myhost:88" + expectedHealthCheckUrlPath);
assertThat(instanceInfo.getSecureHealthCheckUrl())
.isEqualTo("https://myhost:8888" + expectedHealthCheckUrlPath);
application.stop().join();
Expand Down

0 comments on commit 51a76ad

Please sign in to comment.