diff --git a/src/main/java/com/vispana/api/model/VespaVersion.java b/src/main/java/com/vispana/api/model/VespaVersion.java new file mode 100644 index 0000000..437373e --- /dev/null +++ b/src/main/java/com/vispana/api/model/VespaVersion.java @@ -0,0 +1,29 @@ +package com.vispana.api.model; + +public record VespaVersion(long major, long minor, long patch) { + + public static VespaVersion fromString(String version) { + + // Vespa use semantic versioning major.minor.patch + var parts = version.split("\\."); + if (parts.length != 3) { + throw new RuntimeException( + String.format("Failed to parse vespa semantic version: %s", version)); + } + + try { + new VespaVersion( + Long.parseLong(parts[0]), Long.parseLong(parts[1]), Long.parseLong(parts[2])); + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("Failed to parse vespa version numbers: %s", version), e); + } + return new VespaVersion( + Long.parseLong(parts[0]), Long.parseLong(parts[1]), Long.parseLong(parts[2])); + } + + @Override + public String toString() { + return major + "." + minor + "." + patch; + } +} diff --git a/src/main/java/com/vispana/api/model/VispanaRoot.java b/src/main/java/com/vispana/api/model/VispanaRoot.java index ba11170..0c207dd 100644 --- a/src/main/java/com/vispana/api/model/VispanaRoot.java +++ b/src/main/java/com/vispana/api/model/VispanaRoot.java @@ -9,4 +9,5 @@ public record VispanaRoot( ConfigNodes config, ContainerNodes container, ContentNodes content, - ApplicationPackage applicationPackage) {} + ApplicationPackage applicationPackage, + VespaVersion vespaVersion) {} diff --git a/src/main/java/com/vispana/vespa/state/VespaStateClient.java b/src/main/java/com/vispana/vespa/state/VespaStateClient.java index 99f4749..3122feb 100644 --- a/src/main/java/com/vispana/vespa/state/VespaStateClient.java +++ b/src/main/java/com/vispana/vespa/state/VespaStateClient.java @@ -54,7 +54,7 @@ public VispanaRoot vespaState(String configHost) { var containerNodes = containerFork.get(); var contentNodes = contentFork.get(); - return new VispanaRoot(configNodes, containerNodes, contentNodes, appPackage); + return new VispanaRoot(configNodes, containerNodes, contentNodes, appPackage, vespaVersion); } catch (Throwable t) { // Since this application is not meant to be exposed outside a perimeter, jut throw // the exception to ease debugging diff --git a/src/main/java/com/vispana/vespa/state/assemblers/ContentAssembler.java b/src/main/java/com/vispana/vespa/state/assemblers/ContentAssembler.java index 46823c3..dc49188 100644 --- a/src/main/java/com/vispana/vespa/state/assemblers/ContentAssembler.java +++ b/src/main/java/com/vispana/vespa/state/assemblers/ContentAssembler.java @@ -7,6 +7,7 @@ import static java.util.stream.Collectors.groupingBy; import com.vispana.api.model.Host; +import com.vispana.api.model.VespaVersion; import com.vispana.api.model.apppackage.ApplicationPackage; import com.vispana.api.model.content.ContentCluster; import com.vispana.api.model.content.ContentData; @@ -38,7 +39,7 @@ public class ContentAssembler { public static ContentNodes assemble( String configHost, - String vespaVersion, + VespaVersion vespaVersion, Map vespaMetrics, String appUrl, ApplicationPackage appPackage) { @@ -153,24 +154,13 @@ private static List fetchSchemas(String configHost, String clusterName) private static List fetchDispatcherData( String configHost, String clusterName, - String vespaVersion, + VespaVersion vespaVersion, final ApplicationPackage appPackage) { - - String[] version = vespaVersion.split("\\."); - - // Assume semantic versioning major.minor.patch - if (version.length != 3) { - throw new RuntimeException("Failed to parse vespa version"); - } - - int majorVersion = Integer.parseInt(version[0]); - int minorVersion = Integer.parseInt(version[1]); - - if (majorVersion == 7) { + if (vespaVersion.major() == 7) { var dispatcherUrl = configHost + "/config/v1/vespa.config.search.dispatch/" + clusterName + "/search"; return requestGet(dispatcherUrl, SearchDispatchSchema.class).getNode(); - } else if (majorVersion == 8 && minorVersion < 323) { + } else if (vespaVersion.major() == 8 && vespaVersion.minor() < 323) { var dispatcherUrl = configHost + "/config/v2/tenant/default/application/default/vespa.config.search.dispatch-nodes/" diff --git a/src/main/java/com/vispana/vespa/state/helpers/VespaVersionFetcher.java b/src/main/java/com/vispana/vespa/state/helpers/VespaVersionFetcher.java index 0975fb2..997852d 100644 --- a/src/main/java/com/vispana/vespa/state/helpers/VespaVersionFetcher.java +++ b/src/main/java/com/vispana/vespa/state/helpers/VespaVersionFetcher.java @@ -2,13 +2,15 @@ import static com.vispana.vespa.state.helpers.Request.requestGet; +import com.vispana.api.model.VespaVersion; import com.vispana.client.vespa.model.ConfigModelSchema; public class VespaVersionFetcher { // this API might be useful to get which container is queryable - public static String fetch(String configHost) { + public static VespaVersion fetch(String configHost) { var url = configHost + "/config/v2/tenant/default/application/default/cloud.config.model"; - return requestGet(url, ConfigModelSchema.class).getVespaVersion(); + String vespaVersion = requestGet(url, ConfigModelSchema.class).getVespaVersion(); + return VespaVersion.fromString(vespaVersion); } } diff --git a/src/main/js/routes/apppackage/app-package.js b/src/main/js/routes/apppackage/app-package.js index e6eef66..9568e75 100644 --- a/src/main/js/routes/apppackage/app-package.js +++ b/src/main/js/routes/apppackage/app-package.js @@ -64,6 +64,9 @@ function AppPackage() {

Generation: {vespaState.applicationPackage.appPackageGeneration}

+

Version: {`${vespaState.vespaVersion.major}.${vespaState.vespaVersion.minor}.${vespaState.vespaVersion.patch}`} +

}) diff --git a/src/test/java/com/vispana/api/model/VespaVersionTest.java b/src/test/java/com/vispana/api/model/VespaVersionTest.java new file mode 100644 index 0000000..537a96b --- /dev/null +++ b/src/test/java/com/vispana/api/model/VespaVersionTest.java @@ -0,0 +1,23 @@ +package com.vispana.api.model; + +import static org.junit.jupiter.api.Assertions.*; + +import org.junit.jupiter.api.Test; + +class VespaVersionTest { + + @Test + void fromString() { + var version = VespaVersion.fromString("7.1.0"); + assertEquals(7, version.major()); + assertEquals(1, version.minor()); + assertEquals(0, version.patch()); + assertEquals("7.1.0", version.toString()); + } + + @Test + void fromStringThrowsOnInvalidVersion() { + assertThrows(RuntimeException.class, () -> VespaVersion.fromString("7.1")); + assertThrows(RuntimeException.class, () -> VespaVersion.fromString("8.323.a")); + } +}