From efa2f841ff8edb11d7e8c715da0c8966c306d809 Mon Sep 17 00:00:00 2001 From: Lucas Ma <7184042+pony-maggie@users.noreply.github.com> Date: Thu, 14 May 2026 21:44:11 +0800 Subject: [PATCH] Handle missing Eureka AMI metadata Fixes gh-3703 Signed-off-by: Lucas Ma <7184042+pony-maggie@users.noreply.github.com> --- .../eureka/server/EurekaController.java | 10 ++++-- .../eureka/server/EurekaControllerTests.java | 35 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java index fd25a2e8ad..a14886ef8b 100644 --- a/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java +++ b/spring-cloud-netflix-eureka-server/src/main/java/org/springframework/cloud/netflix/eureka/server/EurekaController.java @@ -176,8 +176,14 @@ private void populateApps(Map model) { String zone = ""; if (info.getDataCenterInfo().getName() == DataCenterInfo.Name.Amazon) { AmazonInfo dcInfo = (AmazonInfo) info.getDataCenterInfo(); - ami = dcInfo.get(AmazonInfo.MetaDataKey.amiId); - zone = dcInfo.get(AmazonInfo.MetaDataKey.availabilityZone); + String amiId = dcInfo.get(AmazonInfo.MetaDataKey.amiId); + if (amiId != null) { + ami = amiId; + } + String availabilityZone = dcInfo.get(AmazonInfo.MetaDataKey.availabilityZone); + if (availabilityZone != null) { + zone = availabilityZone; + } } Integer count = amiCounts.get(ami); if (count != null) { diff --git a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaControllerTests.java b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaControllerTests.java index 61d2caf980..43a0a829f5 100644 --- a/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaControllerTests.java +++ b/spring-cloud-netflix-eureka-server/src/test/java/org/springframework/cloud/netflix/eureka/server/EurekaControllerTests.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; +import com.netflix.appinfo.AmazonInfo; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.DataCenterInfo; import com.netflix.appinfo.InstanceInfo; @@ -117,6 +118,33 @@ void testStatus() { assertThat((Boolean) instance.get("isHref")).as("isHref was wrong").isFalse(); } + @Test + void statusUsesDefaultAmiForAmazonInstancesWithoutAmiMetadata() { + AmazonInfo amazonInfo = new AmazonInfo(null, new HashMap<>()); + Application app = new Application("myapp"); + app.addInstance(InstanceInfo.Builder.newBuilder() + .setAppName("myapp") + .setDataCenterInfo(amazonInfo) + .setInstanceId("myapp:1") + .build()); + + when(getServerContext().getRegistry().getSortedApplications()).thenReturn(Collections.singletonList(app)); + + Map model = new HashMap<>(); + EurekaController controller = new EurekaController(infoManager, new EurekaProperties()); + + controller.status(new MockHttpServletRequest("GET", "/"), model); + + Map appData = getFirst(model, "apps"); + Map.Entry amiCount = getFirstEntry(appData, "amiCounts"); + assertThat(amiCount.getKey()).isEqualTo("n/a"); + assertThat(amiCount.getValue()).isEqualTo(1); + } + + private EurekaServerContext getServerContext() { + return EurekaServerContextHolder.getInstance().getServerContext(); + } + @SuppressWarnings("unchecked") Map getFirst(Map model, String key) { List> apps = (List>) model.get(key); @@ -124,4 +152,11 @@ Map getFirst(Map model, String key) { return apps.get(0); } + @SuppressWarnings("unchecked") + Map.Entry getFirstEntry(Map model, String key) { + Iterable> entries = (Iterable>) model.get(key); + assertThat(entries).as(key + " was wrong size").hasSize(1); + return entries.iterator().next(); + } + }