diff --git a/core/pom.xml b/core/pom.xml index a39e505e..2f2debd9 100644 --- a/core/pom.xml +++ b/core/pom.xml @@ -43,14 +43,6 @@ org.bouncycastle bcpkix-jdk18on - - dev.streamx - streamx-runner - - - dev.streamx - streamx-operator-mesh-api - com.fasterxml.jackson.datatype jackson-datatype-jdk8 @@ -67,6 +59,11 @@ commons-codec commons-codec + + org.jetbrains + annotations + 26.0.2-1 + com.jayway.jsonpath json-path @@ -119,6 +116,31 @@ kubernetes-httpclient-okhttp test + + org.testcontainers + testcontainers-bom + 2.0.2 + pom + import + + + org.apache.commons + commons-lang3 + 3.20.0 + compile + + + com.google.guava + guava + 33.5.0-jre + compile + + + org.bouncycastle + bcprov-jdk18on + 1.83 + compile + diff --git a/core/src/main/java/dev/streamx/cli/BannerPrinter.java b/core/src/main/java/dev/streamx/cli/BannerPrinter.java index ee98e3c7..91a17053 100644 --- a/core/src/main/java/dev/streamx/cli/BannerPrinter.java +++ b/core/src/main/java/dev/streamx/cli/BannerPrinter.java @@ -2,8 +2,6 @@ import static dev.streamx.cli.util.Output.print; -import dev.streamx.cli.command.dev.DevCommand; -import dev.streamx.cli.command.run.RunCommand; import jakarta.enterprise.context.ApplicationScoped; import java.util.Set; import picocli.CommandLine; @@ -13,7 +11,7 @@ public class BannerPrinter { private static final Set COMMANDS_REQUIRING_PRINTING_BANNER = - Set.of(DevCommand.COMMAND_NAME, RunCommand.COMMAND_NAME); + Set.of(); private static final String BANNER = """ ____ _ __ __ diff --git a/core/src/main/java/dev/streamx/cli/StreamxCommand.java b/core/src/main/java/dev/streamx/cli/StreamxCommand.java index c16b95aa..4cb6132f 100644 --- a/core/src/main/java/dev/streamx/cli/StreamxCommand.java +++ b/core/src/main/java/dev/streamx/cli/StreamxCommand.java @@ -1,14 +1,10 @@ package dev.streamx.cli; -import dev.streamx.cli.command.cloud.deploy.DeployCommand; -import dev.streamx.cli.command.cloud.undeploy.UndeployCommand; -import dev.streamx.cli.command.dev.DevCommand; import dev.streamx.cli.command.ingestion.batch.BatchCommand; import dev.streamx.cli.command.ingestion.publish.PublishCommand; import dev.streamx.cli.command.ingestion.stream.StreamCommand; import dev.streamx.cli.command.ingestion.unpublish.UnpublishCommand; import dev.streamx.cli.command.init.InitCommand; -import dev.streamx.cli.command.run.RunCommand; import dev.streamx.cli.config.ArgumentConfigSource; import dev.streamx.cli.config.validation.ConfigSourcesValidator; import dev.streamx.cli.license.LicenseArguments; @@ -31,10 +27,8 @@ name = "streamx", subcommands = { InitCommand.class, - RunCommand.class, DevCommand.class, PublishCommand.class, UnpublishCommand.class, BatchCommand.class, StreamCommand.class, - DeployCommand.class, UndeployCommand.class, HelpCommand.class }, versionProvider = VersionProvider.class) diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/KubernetesService.java b/core/src/main/java/dev/streamx/cli/command/cloud/KubernetesService.java deleted file mode 100644 index 3d5f7289..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/KubernetesService.java +++ /dev/null @@ -1,147 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import static dev.streamx.cli.command.cloud.MetadataUtils.CONFIG_TYPE_LABEL; -import static dev.streamx.cli.command.cloud.MetadataUtils.DEFAULT_K8S_NAMESPACE; -import static dev.streamx.cli.command.cloud.MetadataUtils.SERVICEMESH_CRD_NAME; -import static dev.streamx.cli.command.cloud.MetadataUtils.setLabel; -import static dev.streamx.cli.command.cloud.MetadataUtils.setMetadata; - -import dev.streamx.cli.command.cloud.collector.ClusterResourcesCollector; -import dev.streamx.cli.command.cloud.collector.TypedClusterResourceCollector; -import dev.streamx.cli.command.cloud.deploy.Config; -import dev.streamx.cli.exception.KubernetesException; -import dev.streamx.operator.Component; -import dev.streamx.operator.crd.ServiceMesh; -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.ConfigMapBuilder; -import io.fabric8.kubernetes.api.model.HasMetadata; -import io.fabric8.kubernetes.api.model.Secret; -import io.fabric8.kubernetes.api.model.SecretBuilder; -import io.fabric8.kubernetes.api.model.apiextensions.v1.CustomResourceDefinition; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.KubernetesClientException; -import io.fabric8.kubernetes.client.dsl.NonDeletingOperation; -import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; - -@ApplicationScoped -public class KubernetesService { - - @Inject - KubernetesClient kubernetesClient; - @Inject - KubernetesConfig kubernetesConfig; - - public void deploy(List resources) { - resources.forEach(this::deploy); - } - - private void deploy(T resource) { - try { - kubernetesClient.resource(resource).inNamespace(getNamespace()) - .createOr(NonDeletingOperation::update); - } catch (KubernetesClientException e) { - throw KubernetesException.kubernetesClientException(e); - } - } - - public void undeploy(String meshName) { - undeploy(collectManagedResources(meshName)); - } - - public void undeploy(List resources) { - try { - resources.forEach(r -> kubernetesClient.resource(r).delete()); - } catch (KubernetesClientException e) { - throw KubernetesException.kubernetesClientException(e); - } - } - - public List collectManagedResources(String meshName) { - List result = new ArrayList<>(); - // Collect mesh - ServiceMesh mesh = kubernetesClient.resources(ServiceMesh.class).inNamespace(getNamespace()) - .withName(meshName).get(); - if (mesh != null) { - result.add(mesh); - } - - // Collect configs and secrets - result.addAll( - new TypedClusterResourceCollector(kubernetesClient, List.of(ConfigMap.class, Secret.class), - getNamespace()).collect(meshName)); - - // Collect other resources controlled by the CLI - result.addAll(new ClusterResourcesCollector(kubernetesClient, - getControlledResourceDefinitions(), getNamespace()).collect(meshName)); - - return result; - } - - public void validateCrdInstallation() { - try { - CustomResourceDefinition crd = kubernetesClient.apiextensions().v1() - .customResourceDefinitions() - .withName(SERVICEMESH_CRD_NAME) - .get(); - if (crd == null) { - throw KubernetesException.serviceMeshCrdNotFound(); - } - } catch (KubernetesClientException e) { - throw KubernetesException.kubernetesClientException(e); - } - } - - @NotNull - public ConfigMap buildConfigMap(String meshName, Config config) { - ConfigMap configMap = new ConfigMapBuilder() - .withNewMetadata() - .endMetadata() - .addToData(config.data()) - .build(); - String sanitizedName = KubernetesResourceUtil.sanitizeName(config.name()); - setMetadata(meshName, Component.EXTERNAL_CONFIG, sanitizedName, configMap); - setLabel(configMap, CONFIG_TYPE_LABEL, config.configType().getLabelValue()); - return configMap; - } - - @NotNull - public Secret buildSecret(String meshName, Config config) { - Secret secret = new SecretBuilder() - .withNewMetadata() - .endMetadata() - .withStringData(config.data()) - .build(); - String sanitizedName = KubernetesResourceUtil.sanitizeName(config.name()); - setMetadata(meshName, Component.EXTERNAL_SECRET, sanitizedName, secret); - setLabel(secret, CONFIG_TYPE_LABEL, config.configType().getLabelValue()); - return secret; - } - - public String getNamespace() { - return kubernetesConfig.namespace() - .orElse(Optional.ofNullable(kubernetesClient.getNamespace()).orElse(DEFAULT_K8S_NAMESPACE)); - } - - public List getResourcePaths() { - return kubernetesConfig.resourceDirectories().map(paths -> Arrays.stream(paths.split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList())).orElse(List.of()); - } - - public List getControlledResourceDefinitions() { - return kubernetesConfig.controlledResourceDefinitions() - .map(paths -> Arrays.stream(paths.split(",")) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList())).orElse(List.of()); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/MetadataUtils.java b/core/src/main/java/dev/streamx/cli/command/cloud/MetadataUtils.java index d2e3205d..46cd7bfd 100644 --- a/core/src/main/java/dev/streamx/cli/command/cloud/MetadataUtils.java +++ b/core/src/main/java/dev/streamx/cli/command/cloud/MetadataUtils.java @@ -1,22 +1,14 @@ package dev.streamx.cli.command.cloud; -import dev.streamx.operator.Component; import io.fabric8.kubernetes.api.model.HasMetadata; -import io.fabric8.kubernetes.client.utils.KubernetesResourceUtil; import java.util.HashMap; import java.util.Map; public class MetadataUtils { - - public static final String NAME_LABEL = "app.kubernetes.io/name"; - public static final String INSTANCE_LABEL = "app.kubernetes.io/instance"; - public static final String COMPONENT_LABEL = "app.kubernetes.io/component"; public static final String MANAGED_BY_LABEL = "app.kubernetes.io/managed-by"; public static final String MANAGED_BY_LABEL_VALUE = "streamx-cli"; - public static final String CONFIG_TYPE_LABEL = "mesh.streamx.dev/config-type"; public static final String PART_OF_LABEL = "app.kubernetes.io/part-of"; public static final String SERVICEMESH_CRD_NAME = "servicemeshes.streamx.dev"; - public static final String DEFAULT_K8S_NAMESPACE = "default"; private MetadataUtils() { // No instances @@ -29,25 +21,11 @@ public static Map createPartOfAndManagedByLabels(String meshName ); } - public static void setMetadata(String meshName, Component component, String name, - HasMetadata resource) { - String instanceName = getResourceName(meshName, component.getShortName(), name); - resource.getMetadata().setName(instanceName); - setLabel(resource, INSTANCE_LABEL, instanceName); - setLabel(resource, COMPONENT_LABEL, component.getName()); - setLabel(resource, NAME_LABEL, name); - setManagedByAndPartOfLabels(resource, meshName); - } - public static void setManagedByAndPartOfLabels(HasMetadata resource, String meshName) { setLabel(resource, PART_OF_LABEL, meshName); setLabel(resource, MANAGED_BY_LABEL, MANAGED_BY_LABEL_VALUE); } - public static String getResourceName(String meshName, String componentName, String name) { - return KubernetesResourceUtil.sanitizeName(meshName + "-" + componentName + "-" + name); - } - public static void setLabel(HasMetadata resource, String key, String value) { if (resource.getMetadata().getLabels() == null) { resource.getMetadata().setLabels(new HashMap<>()); diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/ProjectPathsResolver.java b/core/src/main/java/dev/streamx/cli/command/cloud/ProjectPathsResolver.java deleted file mode 100644 index 14d9b397..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/ProjectPathsResolver.java +++ /dev/null @@ -1,38 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import dev.streamx.cli.command.meshprocessing.MeshResolver; -import jakarta.enterprise.context.ApplicationScoped; -import java.nio.file.Path; -import org.jetbrains.annotations.NotNull; - -@ApplicationScoped -public class ProjectPathsResolver { - - public static final String CONFIGS_DIRECTORY = "configs"; - public static final String SECRETS_DIRECTORY = "secrets"; - protected static final String YAML_EXT = ".yaml"; - static final String DEPLOYMENT = "deployment"; - static final String DEPLOYMENT_FILE_NAME = DEPLOYMENT + YAML_EXT; - - @NotNull - public Path resolveDeploymentPath(Path meshPath) { - String meshFileName = meshPath.getFileName().toString(); - String deploymentFileName = DEPLOYMENT_FILE_NAME; - if (!MeshResolver.MESH_YAML.equals(meshFileName)) { - deploymentFileName = DEPLOYMENT + "." + meshFileName; - } - return meshPath.getParent().resolve(deploymentFileName); - } - - public Path resolveSecretPath(Path projectPath, String sourcePath) { - return resolveSourcePath(projectPath, SECRETS_DIRECTORY, sourcePath); - } - - public Path resolveConfigPath(Path projectPath, String sourcePath) { - return resolveSourcePath(projectPath, CONFIGS_DIRECTORY, sourcePath); - } - - private Path resolveSourcePath(Path projectPath, String sourceDirectory, String sourcePath) { - return projectPath.resolve(sourceDirectory).resolve(sourcePath); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/ServiceMeshResolver.java b/core/src/main/java/dev/streamx/cli/command/cloud/ServiceMeshResolver.java deleted file mode 100644 index 0b963aa0..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/ServiceMeshResolver.java +++ /dev/null @@ -1,182 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import com.fasterxml.jackson.databind.ObjectMapper; -import dev.streamx.cli.interpolation.Interpolating; -import dev.streamx.cli.util.ExceptionUtils; -import dev.streamx.mesh.model.AbstractContainer; -import dev.streamx.mesh.model.AbstractFromSource; -import dev.streamx.mesh.model.DeliveryService; -import dev.streamx.mesh.model.EnvironmentFrom; -import dev.streamx.mesh.model.VolumesFrom; -import dev.streamx.operator.crd.ServiceMesh; -import dev.streamx.operator.crd.ServiceMeshSpec; -import dev.streamx.operator.crd.deployment.ServiceMeshDeploymentConfig; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.io.File; -import java.io.IOException; -import java.nio.file.Path; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -@ApplicationScoped -public class ServiceMeshResolver { - - public static final String SERVICE_MESH_NAME = "sx"; - @Inject - @Interpolating - ObjectMapper objectMapper; - - @Inject - ProjectPathsResolver projectPathsResolver; - - @NotNull - public ServiceMesh resolveMesh(Path meshPath) { - File meshPathFile = meshPath.toFile(); - if (!meshPathFile.exists()) { - throw new RuntimeException("Mesh file with provided path '" + meshPath + "' does not exist."); - } - if (meshPathFile.length() < 1) { - throw new RuntimeException("Mesh file with provided path '" + meshPath + "' is empty."); - } - ServiceMesh serviceMesh = new ServiceMesh(); - try { - ServiceMeshSpec spec = objectMapper.readValue(meshPathFile, - ServiceMeshSpec.class); - ServiceMeshDeploymentConfig serviceMeshDeploymentConfig = readDeploymentConfig(meshPath); - spec.setDeploymentConfig(serviceMeshDeploymentConfig); - serviceMesh.setSpec(spec); - serviceMesh.getMetadata().setName(SERVICE_MESH_NAME); - } catch (IOException e) { - throw new RuntimeException( - ExceptionUtils.appendLogSuggestion( - "Unable to read mesh definition from '" + meshPath + "'.\n" - + "\n" - + "Details:\n" - + e.getMessage()), e); - } - return serviceMesh; - } - - @NotNull - public ConfigSourcesPaths extractConfigSourcesPaths(ServiceMesh serviceMesh) { - Set configEnvPaths = new HashSet<>(); - Set secretEnvPaths = new HashSet<>(); - Set configVolumePaths = new HashSet<>(); - Set secretVolumePaths = new HashSet<>(); - processGlobalEnvSources(serviceMesh, configEnvPaths, secretEnvPaths); - List containers = extractContainers(serviceMesh); - containers.forEach(container -> { - EnvironmentFrom environmentFrom = container.getEnvironmentFrom(); - configEnvPaths.addAll( - extractConfigSourcesPaths(environmentFrom, AbstractFromSource::getConfigs, null)); - secretEnvPaths.addAll( - extractConfigSourcesPaths(environmentFrom, AbstractFromSource::getSecrets, null)); - VolumesFrom volumesFrom = container.getVolumesFrom(); - configVolumePaths.addAll( - extractConfigSourcesPaths(volumesFrom, AbstractFromSource::getConfigs, - this::mapToHostPath)); - secretVolumePaths.addAll( - extractConfigSourcesPaths(volumesFrom, AbstractFromSource::getSecrets, - this::mapToHostPath)); - }); - - return new ConfigSourcesPaths(configEnvPaths, secretEnvPaths, configVolumePaths, - secretVolumePaths); - } - - @NotNull - private List extractConfigSourcesPaths(AbstractFromSource fromSource, - Function> pathsExtractor, Function mapper) { - List configsPaths = Collections.emptyList(); - if (fromSource != null) { - List extractedPaths = pathsExtractor.apply(fromSource); - if (extractedPaths != null) { - configsPaths = extractedPaths.stream().filter(Objects::nonNull).toList(); - if (mapper != null) { - configsPaths = configsPaths.stream().map(mapper).collect(Collectors.toList()); - } - } - } - return configsPaths; - } - - @Nullable - private ServiceMeshDeploymentConfig readDeploymentConfig(Path meshPath) { - Path deploymentPath = projectPathsResolver.resolveDeploymentPath(meshPath); - ServiceMeshDeploymentConfig serviceMeshDeploymentConfig = null; - File deploymentFile = deploymentPath.toFile(); - if (deploymentFile.exists() && deploymentFile.length() > 0) { - try { - serviceMeshDeploymentConfig = objectMapper.readValue(deploymentFile, - ServiceMeshDeploymentConfig.class); - } catch (IOException e) { - throw new RuntimeException( - ExceptionUtils.appendLogSuggestion( - "Unable to read deployment from '" + deploymentPath + "'.\n" - + "\n" - + "Details:\n" - + e.getMessage()), e); - } - } - return serviceMeshDeploymentConfig; - } - - @NotNull - List extractContainers(ServiceMesh serviceMesh) { - ServiceMeshSpec serviceMeshSpec = serviceMesh.getSpec(); - List containers = Stream.of( - serviceMeshSpec.getIngestion(), - serviceMeshSpec.getProcessing(), - serviceMeshSpec.getDelivery() - ).filter(Objects::nonNull).map(Map::values) - .flatMap(Collection::stream).collect(Collectors.toList()); - containers.addAll( - Optional.ofNullable(serviceMeshSpec.getDelivery()) - .orElse(Collections.emptyMap()) - .values() - .stream() - .map(DeliveryService::getComponents) - .filter(Objects::nonNull) - .map(Map::values) - .flatMap(Collection::stream) - .toList() - ); - return containers; - } - - private void processGlobalEnvSources(ServiceMesh serviceMesh, Set envConfigsPaths, - Set envSecretsPaths) { - EnvironmentFrom globalEnvironmentFrom = serviceMesh.getSpec().getEnvironmentFrom(); - if (globalEnvironmentFrom != null) { - List globalEnvironmentFromConfigs = globalEnvironmentFrom.getConfigs(); - if (globalEnvironmentFromConfigs != null) { - envConfigsPaths.addAll(globalEnvironmentFromConfigs); - } - List globalEnvironmentFromSecrets = globalEnvironmentFrom.getSecrets(); - if (globalEnvironmentFromSecrets != null) { - envSecretsPaths.addAll(globalEnvironmentFromSecrets); - } - } - } - - private String mapToHostPath(String volumeConf) { - return volumeConf.split(":")[0]; - } - - public record ConfigSourcesPaths(Set configEnvPaths, Set secretEnvPaths, - Set configVolumePaths, Set secretVolumePaths) { - - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/Config.java b/core/src/main/java/dev/streamx/cli/command/cloud/deploy/Config.java deleted file mode 100644 index 3b51421e..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/Config.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import java.util.Map; - -public record Config(String name, Map data, ConfigType configType) { - - public enum ConfigType { - DIR, FILE; - - public String getLabelValue() { - return this.toString().toLowerCase(); - } - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ConfigService.java b/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ConfigService.java deleted file mode 100644 index 44d31829..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ConfigService.java +++ /dev/null @@ -1,77 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import dev.streamx.cli.command.cloud.ProjectPathsResolver; -import dev.streamx.cli.command.cloud.deploy.Config.ConfigType; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.io.File; -import java.nio.file.Path; -import java.util.Map; -import java.util.function.Function; -import org.jetbrains.annotations.NotNull; - -@ApplicationScoped -public class ConfigService { - - @Inject - DataService dataService; - - @Inject - ProjectPathsResolver projectPathsResolver; - - @NotNull - public Config getSecretVolume(Path projectPath, String configPath) { - return getConfig(configPath, getSecretConfigPathMapper(projectPath), - dataService::loadDataFromFiles, this::getConfigType); - } - - @NotNull - public Config getConfigVolume(Path projectPath, String configPath) { - return getConfig(configPath, getConfigPathMapper(projectPath), - dataService::loadDataFromFiles, this::getConfigType); - } - - @NotNull - public Config getSecretEnv(Path projectPath, String configPath) { - return getConfig(configPath, getSecretConfigPathMapper(projectPath), - dataService::loadDataFromProperties, path -> ConfigType.FILE); - } - - @NotNull - public Config getConfigEnv(Path projectPath, String configPath) { - return getConfig(configPath, getConfigPathMapper(projectPath), - dataService::loadDataFromProperties, path -> ConfigType.FILE); - } - - @NotNull - private Function getSecretConfigPathMapper(Path projectPath) { - return (path) -> projectPathsResolver.resolveSecretPath(projectPath, path); - } - - @NotNull - private Function getConfigPathMapper(Path projectPath) { - return (path) -> projectPathsResolver.resolveConfigPath(projectPath, path); - } - - @NotNull - private Config getConfig(String configPath, Function pathMapper, - Function> dataMapper, Function configTypeMapper) { - Path mappedPath = pathMapper.apply(configPath); - Map data = dataMapper.apply(mappedPath); - ConfigType configType = configTypeMapper.apply(mappedPath); - return new Config(configPath, data, configType); - } - - @NotNull - ConfigType getConfigType(Path dataSourcePath) { - File dataSource = dataSourcePath.toFile(); - if (dataSource.isFile()) { - return ConfigType.FILE; - } - if (dataSource.isDirectory()) { - return ConfigType.DIR; - } - throw new IllegalStateException( - "Config source " + dataSource + " provided in Mesh should be file or directory."); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/DataService.java b/core/src/main/java/dev/streamx/cli/command/cloud/deploy/DataService.java deleted file mode 100644 index 8dce4263..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/DataService.java +++ /dev/null @@ -1,99 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import jakarta.enterprise.context.ApplicationScoped; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Stream; - -@ApplicationScoped -public class DataService { - - private static final Pattern validKeyPattern = Pattern.compile("[-._a-zA-Z0-9]+"); - - public Map loadDataFromProperties(Path propertiesFilePath) { - File propertiesFile = propertiesFilePath.toFile(); - if (!propertiesFile.exists() || !propertiesFile.isFile()) { - throw new IllegalStateException("Path " + propertiesFilePath.normalize() - + " provided in Mesh must be a valid properties file."); - } - Properties properties = new Properties(); - try (FileInputStream fis = new FileInputStream(propertiesFile)) { - properties.load(fis); - Map data = new HashMap<>(); - for (Map.Entry entry : properties.entrySet()) { - String propertyKey = entry.getKey().toString(); - validatePropertyKey(propertiesFilePath.toString(), propertyKey); - data.put(propertyKey, entry.getValue().toString()); - } - return data; - } catch (IOException e) { - throw new IllegalStateException("Error reading properties file: " + propertiesFile, e); - } - } - - public Map loadDataFromFiles(Path path) { - Map data = new HashMap<>(); - try { - if (Files.isRegularFile(path)) { - loadDataFromFile(path.toString(), path, data); - } else if (Files.isDirectory(path)) { - try (Stream walk = Files.walk(path, 1)) { - walk - .filter(Files::isRegularFile) - .forEach(file -> { - try { - loadDataFromFile(path.toString(), file, data); - } catch (IOException e) { - throw new RuntimeException("Failed to read data file: " + file.toAbsolutePath(), - e); - } - }); - } - } else { - throw new IllegalArgumentException( - "Path " + path.normalize() + " provided in Mesh must be a file or a directory."); - } - } catch (IOException e) { - throw new IllegalStateException("Failed to convert " + path.normalize() + " to data", e); - } - - return data; - } - - private void loadDataFromFile(String configPath, Path filePath, Map data) - throws IOException { - String content = Files.readString(filePath); - String fileName = filePath.getFileName().toString(); - validateFileName(configPath, fileName); - data.put(fileName, content); - } - - private void validateFileName(String configPath, String fileName) { - if (isConfigDataKeyInvalid(fileName)) { - throw new IllegalArgumentException( - "Invalid file name: " + fileName + " in volumesFrom: " + configPath - + ". Valid file name must consist of alphanumeric characters, '-', '_' or '.'."); - } - } - - private void validatePropertyKey(String configPath, String key) { - if (isConfigDataKeyInvalid(key)) { - throw new IllegalArgumentException( - "Invalid properties key: " + key + " in environmentFrom: " + configPath - + ". Valid property key must consist of alphanumeric characters, '-', '_' or '.'."); - } - } - - private boolean isConfigDataKeyInvalid(String key) { - Matcher matcher = validKeyPattern.matcher(key); - return !matcher.matches(); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/DeployCommand.java b/core/src/main/java/dev/streamx/cli/command/cloud/deploy/DeployCommand.java deleted file mode 100644 index 4ec4112f..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/DeployCommand.java +++ /dev/null @@ -1,123 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import static dev.streamx.cli.util.Output.printf; - -import com.fasterxml.jackson.databind.ObjectMapper; -import dev.streamx.cli.VersionProvider; -import dev.streamx.cli.command.cloud.KubernetesArguments; -import dev.streamx.cli.command.cloud.KubernetesService; -import dev.streamx.cli.command.cloud.ServiceMeshResolver; -import dev.streamx.cli.command.cloud.ServiceMeshResolver.ConfigSourcesPaths; -import dev.streamx.cli.command.cloud.collector.DirectoryResourcesCollector; -import dev.streamx.cli.command.cloud.collector.KubernetesResourcesCollector; -import dev.streamx.cli.command.meshprocessing.MeshConfig; -import dev.streamx.cli.command.meshprocessing.MeshResolver; -import dev.streamx.cli.command.meshprocessing.MeshSource; -import dev.streamx.cli.interpolation.Interpolating; -import dev.streamx.operator.crd.ServiceMesh; -import io.fabric8.kubernetes.api.model.HasMetadata; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import picocli.CommandLine.ArgGroup; -import picocli.CommandLine.Command; - -@Command( - name = DeployCommand.COMMAND_NAME, - mixinStandardHelpOptions = true, - versionProvider = VersionProvider.class, - description = "Deploy the StreamX project to the cloud.", - footer = DeployCommand.CLOUD_COMMAND_FOOTER -) -public class DeployCommand implements Runnable { - - public static final String COMMAND_NAME = "deploy"; - - public static final String CLOUD_COMMAND_FOOTER = """ - - The command automatically uses the cluster connection and namespace settings from the \ - current context in your @|italic kubeconfig|@ file. Ensure that your @|italic kubeconfig|@ \ - is configured correctly and pointing to the desired cluster and namespace. You can verify \ - your current context and namespace by running: - - @|yellow kubectl config current-context|@ - @|yellow kubectl config view --minify | grep namespace|@ - - If necessary, switch to the correct context using: - - @|yellow kubectl config use-context |@ - - This command assumes the StreamX Operator is installed and the required CRDs are available \ - on the target cluster. If not, please install the operator and ensure the cluster meets \ - the prerequisites before running this command."""; - - @ArgGroup - MeshSource meshSource; - - @ArgGroup(exclusive = false) - KubernetesArguments kubernetesArguments; - - @Inject - MeshConfig meshConfig; - - @Inject - MeshResolver meshResolver; - - @Inject - ServiceMeshResolver serviceMeshResolver; - - @Inject - KubernetesService kubernetesService; - - @Inject - ProjectResourcesExtractor projectResourcesExtractor; - - @Inject - @Interpolating - ObjectMapper objectMapper; - - @Override - public void run() { - Path meshPath = meshResolver.resolveMeshPath(meshConfig); - meshPath = meshPath.toAbsolutePath(); - ServiceMesh serviceMesh = serviceMeshResolver.resolveMesh(meshPath); - Path projectPath = meshPath.getParent(); - deploy(serviceMesh, projectPath); - } - - private void deploy(ServiceMesh serviceMesh, Path projectPath) { - kubernetesService.validateCrdInstallation(); - ConfigSourcesPaths configPaths = serviceMeshResolver.extractConfigSourcesPaths(serviceMesh); - String serviceMeshName = serviceMesh.getMetadata().getName(); - - List resourcesToDeploy = new ArrayList<>(); - List managedResources = kubernetesService.collectManagedResources(serviceMeshName); - - // Collect all resources to deploy - resourcesToDeploy.addAll(collectKubernetesResources(projectPath, serviceMeshName)); - resourcesToDeploy.addAll( - projectResourcesExtractor.getSecrets(projectPath, configPaths, serviceMeshName)); - resourcesToDeploy.addAll( - projectResourcesExtractor.getConfigMaps(projectPath, configPaths, serviceMeshName)); - resourcesToDeploy.add(serviceMesh); - - // Collect all resources to delete - ResourceCleaner cleaner = new ResourceCleaner(resourcesToDeploy, managedResources); - kubernetesService.deploy(resourcesToDeploy); - printf("Project %s successfully deployed to '%s' namespace.%n", - projectPath.toAbsolutePath().normalize(), kubernetesService.getNamespace()); - List orphanedResources = cleaner.getOrphanedResources(); - printf("Deleting %d orphaned resources.\n", orphanedResources.size()); - kubernetesService.undeploy(orphanedResources); - - } - - private List collectKubernetesResources(Path projectPath, String serviceMeshName) { - List resourcesDirectories = kubernetesService.getResourcePaths(); - - KubernetesResourcesCollector collector = new DirectoryResourcesCollector(objectMapper, - projectPath, resourcesDirectories); - return collector.collect(serviceMeshName); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ProjectResourcesExtractor.java b/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ProjectResourcesExtractor.java deleted file mode 100644 index 178ed241..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ProjectResourcesExtractor.java +++ /dev/null @@ -1,80 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import dev.streamx.cli.command.cloud.KubernetesService; -import dev.streamx.cli.command.cloud.ServiceMeshResolver.ConfigSourcesPaths; -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.Secret; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; -import java.util.stream.Stream; -import org.jetbrains.annotations.NotNull; - -@ApplicationScoped -public class ProjectResourcesExtractor { - - @Inject - ConfigService configService; - - @Inject - KubernetesService kubernetesService; - - @NotNull - public List getSecrets(Path projectPath, ConfigSourcesPaths configSourcesPaths, - String serviceMeshName) { - List<@NotNull Secret> envSecrets = getEnvSecrets(projectPath, - configSourcesPaths.secretEnvPaths(), - serviceMeshName); - List<@NotNull Secret> volumeSecrets = getVolumeSecrets(projectPath, - configSourcesPaths.secretVolumePaths(), serviceMeshName); - return Stream.concat(envSecrets.stream(), volumeSecrets.stream()).toList(); - } - - @NotNull - public List getConfigMaps(Path projectPath, ConfigSourcesPaths configSourcesPaths, - String serviceMeshName) { - List<@NotNull ConfigMap> envConfigMaps = getEnvConfigMaps(projectPath, - configSourcesPaths.configEnvPaths(), serviceMeshName); - List<@NotNull ConfigMap> volumeConfigMaps = getVolumeConfigMaps(projectPath, - configSourcesPaths.configVolumePaths(), serviceMeshName); - return Stream.concat(envConfigMaps.stream(), volumeConfigMaps.stream()).toList(); - } - - @NotNull - private List<@NotNull Secret> getVolumeSecrets(Path projectPath, Set volumePaths, - String serviceMeshName) { - return volumePaths.stream() - .map(path -> configService.getSecretVolume(projectPath, path)) - .map(config -> kubernetesService.buildSecret(serviceMeshName, config)) - .toList(); - } - - @NotNull - private List<@NotNull Secret> getEnvSecrets(Path projectPath, Set envPaths, - String serviceMeshName) { - return envPaths.stream() - .map(path -> configService.getSecretEnv(projectPath, path)) - .map(config -> kubernetesService.buildSecret(serviceMeshName, config)) - .toList(); - } - - @NotNull - private List<@NotNull ConfigMap> getEnvConfigMaps(Path projectPath, Set envPaths, - String serviceMeshName) { - return envPaths.stream() - .map(path -> configService.getConfigEnv(projectPath, path)) - .map(config -> kubernetesService.buildConfigMap(serviceMeshName, config)) - .toList(); - } - - @NotNull - private List<@NotNull ConfigMap> getVolumeConfigMaps(Path projectPath, Set volumePaths, - String serviceMeshName) { - return volumePaths.stream() - .map(path -> configService.getConfigVolume(projectPath, path)) - .map(config -> kubernetesService.buildConfigMap(serviceMeshName, config)) - .toList(); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ResourceCleaner.java b/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ResourceCleaner.java deleted file mode 100644 index 5047c859..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/deploy/ResourceCleaner.java +++ /dev/null @@ -1,47 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import io.fabric8.kubernetes.api.model.HasMetadata; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public class ResourceCleaner { - - private final List resourcesToDeploy; - private final List managedResources; - - /** - * Constructor takes two lists: - * - * @param resourcesToDeploy list of resources planned for deployment - * @param managedResources list of currently managed resources - */ - public ResourceCleaner(List resourcesToDeploy, List managedResources) { - this.resourcesToDeploy = resourcesToDeploy; - this.managedResources = managedResources; - } - - /** - * Returns the list of orphaned managed resources, i.e. those managed resources that are not - * present in the deployment list, based on namespace and name. - * - * @return List of resources to remove. - */ - public List getOrphanedResources() { - // Build a set of keys (namespace/name) for resources to deploy. - Set deployKeys = resourcesToDeploy.stream() - .map(this::keyFor) - .collect(Collectors.toSet()); - - // Filter managedResources to keep only those not present in deployKeys. - return managedResources.stream() - .filter(resource -> !deployKeys.contains(keyFor(resource))) - .collect(Collectors.toList()); - } - - private String keyFor(HasMetadata resource) { - String api = resource.getApiVersion() + "/" + resource.getKind(); - String name = resource.getMetadata().getName(); - return api + "/" + name; - } -} \ No newline at end of file diff --git a/core/src/main/java/dev/streamx/cli/command/cloud/undeploy/UndeployCommand.java b/core/src/main/java/dev/streamx/cli/command/cloud/undeploy/UndeployCommand.java deleted file mode 100644 index eb439bac..00000000 --- a/core/src/main/java/dev/streamx/cli/command/cloud/undeploy/UndeployCommand.java +++ /dev/null @@ -1,38 +0,0 @@ -package dev.streamx.cli.command.cloud.undeploy; - -import static dev.streamx.cli.command.cloud.ServiceMeshResolver.SERVICE_MESH_NAME; -import static dev.streamx.cli.util.Output.printf; - -import dev.streamx.cli.VersionProvider; -import dev.streamx.cli.command.cloud.KubernetesArguments; -import dev.streamx.cli.command.cloud.KubernetesService; -import dev.streamx.cli.command.cloud.deploy.DeployCommand; -import jakarta.inject.Inject; -import picocli.CommandLine.ArgGroup; -import picocli.CommandLine.Command; - -@Command( - name = UndeployCommand.COMMAND_NAME, - mixinStandardHelpOptions = true, - versionProvider = VersionProvider.class, - description = "Undeploy the StreamX Project from the cloud.", - footer = DeployCommand.CLOUD_COMMAND_FOOTER -) -public class UndeployCommand implements Runnable { - - public static final String COMMAND_NAME = "undeploy"; - - @ArgGroup(exclusive = false) - KubernetesArguments kubernetesArguments; - @Inject - KubernetesService kubernetesService; - - @Override - public void run() { - kubernetesService.validateCrdInstallation(); - kubernetesService.undeploy(SERVICE_MESH_NAME); - - printf("StreamX project successfully undeployed from '%s' namespace.%n", - kubernetesService.getNamespace()); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/BrowserOpener.java b/core/src/main/java/dev/streamx/cli/command/dev/BrowserOpener.java deleted file mode 100644 index 6448571a..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/BrowserOpener.java +++ /dev/null @@ -1,36 +0,0 @@ -package dev.streamx.cli.command.dev; - -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.awt.Desktop; -import java.net.URI; -import org.jboss.logging.Logger; - -@ApplicationScoped -public class BrowserOpener { - - @Inject - Logger logger; - - @Inject - DevConfig devConfig; - - public void tryOpenBrowser() { - if (!devConfig.openOnStart()) { - return; - } - - try { - if (Desktop.isDesktopSupported()) { - Desktop desktop = Desktop.getDesktop(); - String entryUrl = "http://localhost:%d/overview".formatted(devConfig.dashboardPort()); - URI meshManagerUri = new URI(entryUrl); - desktop.browse(meshManagerUri); - } else { - logger.warn("Opening browser is not supported"); - } - } catch (Exception e) { - logger.error("Opening browser failed", e); - } - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/DashboardContainer.java b/core/src/main/java/dev/streamx/cli/command/dev/DashboardContainer.java deleted file mode 100644 index 7c032368..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/DashboardContainer.java +++ /dev/null @@ -1,31 +0,0 @@ -package dev.streamx.cli.command.dev; - -import java.util.List; -import org.testcontainers.containers.BindMode; -import org.testcontainers.containers.GenericContainer; -import org.testcontainers.utility.DockerImageName; - -public class DashboardContainer extends GenericContainer { - - public static final String CONTAINER_NAME = "streamx-dashboard"; - - private static final int DASHBOARDS_CONTAINER_PORT = 8080; - - public DashboardContainer(String fullImageName, int exposedPort, String meshPath, - String meshDirectory, String projectDirectory) { - super(DockerImageName.parse(fullImageName)); - setExposedPorts(List.of(DASHBOARDS_CONTAINER_PORT)); - addFixedExposedPort(exposedPort, DASHBOARDS_CONTAINER_PORT); - - withFileSystemBind(meshPath, "/data/mesh.yaml", BindMode.READ_WRITE); - withFileSystemBind(meshDirectory, "/data/mesh", BindMode.READ_WRITE); - - if (projectDirectory != null) { - withFileSystemBind(projectDirectory, "/data/project", BindMode.READ_WRITE); - } - - withCreateContainerCmdModifier(cmd -> cmd.withName(CONTAINER_NAME)); - withEnv("streamx.platform.mesh.services-metadata-registry-roots", - "/data/project/services,/data/mesh/services"); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/DashboardRunner.java b/core/src/main/java/dev/streamx/cli/command/dev/DashboardRunner.java deleted file mode 100644 index f2c2a171..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/DashboardRunner.java +++ /dev/null @@ -1,56 +0,0 @@ -package dev.streamx.cli.command.dev; - -import static dev.streamx.cli.util.Output.print; - -import dev.streamx.cli.command.dev.event.DashboardStarted; -import dev.streamx.cli.util.StreamxMavenPropertiesUtils; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Event; -import jakarta.inject.Inject; -import java.time.Duration; -import org.testcontainers.containers.Network; -import org.testcontainers.containers.wait.strategy.Wait; - -@ApplicationScoped -public class DashboardRunner { - private static final long CONTAINER_TIMEOUT_IN_SECS = 60_000L; - - @Inject - DevConfig devConfig; - - @Inject - BrowserOpener browserOpener; - - @Inject - Event dashboardStartedEvent; - - private DashboardContainer dashboardContainer; - - public void startStreamxDashboard(String meshPath, String meshDirectory, - String projectDirectory, Network network) { - dashboardContainer = new DashboardContainer( - StreamxMavenPropertiesUtils.getDashboardImage(), - devConfig.dashboardPort(), - meshPath, - meshDirectory, - projectDirectory - ) - .withNetwork(network) - .waitingFor(Wait.forHttp("/q/health") - .forPort(8080) - ) - .withStartupTimeout(Duration.ofSeconds(CONTAINER_TIMEOUT_IN_SECS)); - - dashboardContainer.start(); - - print("StreamX Dashboard started on http://localhost:" + devConfig.dashboardPort()); - - browserOpener.tryOpenBrowser(); - dashboardStartedEvent.fire(new DashboardStarted()); - } - - public void stopStreamxDashboard() { - dashboardContainer.stop(); - print("StreamX Dashboard stopped"); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/DevCommand.java b/core/src/main/java/dev/streamx/cli/command/dev/DevCommand.java deleted file mode 100644 index 0a0e8b69..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/DevCommand.java +++ /dev/null @@ -1,135 +0,0 @@ -package dev.streamx.cli.command.dev; - -import static dev.streamx.cli.util.Output.print; - -import dev.streamx.cli.BannerPrinter; -import dev.streamx.cli.VersionProvider; -import dev.streamx.cli.command.dev.event.DevReady; -import dev.streamx.cli.command.meshprocessing.MeshConfig; -import dev.streamx.cli.command.meshprocessing.MeshManager; -import dev.streamx.cli.command.meshprocessing.MeshResolver; -import dev.streamx.cli.command.meshprocessing.MeshSource; -import dev.streamx.cli.command.meshprocessing.MeshWatcher; -import dev.streamx.cli.exception.DockerException; -import dev.streamx.runner.StreamxRunner; -import dev.streamx.runner.container.PulsarContainer; -import dev.streamx.runner.exception.ContainerStartupTimeoutException; -import io.quarkus.runtime.Quarkus; -import jakarta.enterprise.event.Event; -import jakarta.inject.Inject; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Set; -import org.jboss.logging.Logger; -import picocli.CommandLine; -import picocli.CommandLine.ArgGroup; -import picocli.CommandLine.Command; -import picocli.CommandLine.Spec; - -@Command(name = DevCommand.COMMAND_NAME, - mixinStandardHelpOptions = true, - versionProvider = VersionProvider.class, - description = "Develop a StreamX Mesh locally.") -public class DevCommand implements Runnable { - - public static final String COMMAND_NAME = "dev"; - - @Inject - Logger logger; - - @ArgGroup - MeshSource meshSource; - - @Spec - CommandLine.Model.CommandSpec spec; - - @Inject - MeshConfig meshConfig; - - @Inject - MeshResolver meshResolver; - - @Inject - DockerValidator dockerValidator; - - @Inject - StreamxRunner runner; - - @Inject - MeshWatcher meshWatcher; - - @Inject - BannerPrinter bannerPrinter; - - @Inject - MeshManager meshManager; - - @Inject - DashboardRunner dashboardRunner; - - @Inject - Event devReadyEvent; - - @Override - public void run() { - try { - Path meshPath = meshResolver.resolveMeshPath(meshConfig, false); - - dockerValidator.validateDockerEnvironment(Set.of( - DashboardContainer.CONTAINER_NAME, - PulsarContainer.NAME - )); - - bannerPrinter.printBanner(); - boolean meshFileExists = meshPath.toFile().exists(); - if (!meshFileExists) { - Files.createFile(meshPath); - } - - this.runner.initializeBase(); - startDashboard(meshPath); - - meshManager.initializeDevMode(meshPath, spec.commandLine()); - meshWatcher.watchMeshChanges(meshPath); - - if (meshFileExists) { - meshManager.start(); - } - - devReadyEvent.fire(new DevReady()); - - Quarkus.waitForExit(); - } catch (ContainerStartupTimeoutException e) { - throw DockerException.containerStartupFailed( - e.getContainerName(), - runner.getContext().getStreamxBaseConfig().getContainerStartupTimeout()); - } catch (IOException e) { - // handle creat file - throw new RuntimeException(e); - } - } - - private void startDashboard(Path meshPath) { - print("Setting up StreamX Dashboard..."); - var meshPathAsString = meshPath.toAbsolutePath().normalize().toString(); - Path meshDirectory = meshPath.resolve(".."); - Path projectDirectory = null; - if (Files.exists(meshDirectory.resolve("..").normalize())) { - projectDirectory = meshDirectory.resolve("..").normalize(); - } - - var meshDirectoryAsString = meshDirectory.toAbsolutePath().normalize().toString(); - var projectDirectoryAsString = projectDirectory != null - ? projectDirectory.toAbsolutePath().normalize().toString() - : null; - - logger.infov("Resolved mesh {0}, mesh directory {1} and project directory {2}", - meshPathAsString, meshDirectoryAsString, projectDirectoryAsString); - dashboardRunner.startStreamxDashboard( - meshPathAsString, - meshDirectoryAsString, - projectDirectoryAsString, - runner.getContext().getNetwork()); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/DevConfig.java b/core/src/main/java/dev/streamx/cli/command/dev/DevConfig.java deleted file mode 100644 index 616bc97d..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/DevConfig.java +++ /dev/null @@ -1,20 +0,0 @@ -package dev.streamx.cli.command.dev; - -import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithDefault; -import io.smallrye.config.WithName; - -@ConfigMapping -public interface DevConfig { - - String STREAMX_DEV_DASHBOARD_PORT = "streamx.dev.dashboard.port"; - String STREAMX_DEV_DASHBOARD_OPEN_ON_STARTUP = "streamx.dev.dashboard.open-on-startup"; - - @WithName(STREAMX_DEV_DASHBOARD_PORT) - @WithDefault("9088") - int dashboardPort(); - - @WithName(STREAMX_DEV_DASHBOARD_OPEN_ON_STARTUP) - @WithDefault("true") - boolean openOnStart(); -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/DockerValidator.java b/core/src/main/java/dev/streamx/cli/command/dev/DockerValidator.java deleted file mode 100644 index 7dfb0c47..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/DockerValidator.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.streamx.cli.command.dev; - -import com.github.dockerjava.api.DockerClient; -import dev.streamx.runner.validation.DockerContainerValidator; -import dev.streamx.runner.validation.DockerEnvironmentValidator; -import jakarta.enterprise.context.Dependent; -import jakarta.inject.Inject; -import java.util.Set; -import org.jboss.logging.Logger; - -@Dependent -public class DockerValidator { - - private static final Logger LOG = Logger.getLogger(DockerValidator.class); - - @Inject - DockerEnvironmentValidator dockerEnvironmentValidator; - - @Inject - DockerContainerValidator dockerContainerValidator; - - public void validateDockerEnvironment(Set validatedContainerNames) { - LOG.info("Validating environment..."); - - DockerClient client = dockerEnvironmentValidator.validateDockerClient(); - dockerContainerValidator.verifyExistingContainers(client, validatedContainerNames); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/event/DashboardStarted.java b/core/src/main/java/dev/streamx/cli/command/dev/event/DashboardStarted.java deleted file mode 100644 index d23e7b49..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/event/DashboardStarted.java +++ /dev/null @@ -1,5 +0,0 @@ -package dev.streamx.cli.command.dev.event; - -public class DashboardStarted { - -} diff --git a/core/src/main/java/dev/streamx/cli/command/dev/event/DevReady.java b/core/src/main/java/dev/streamx/cli/command/dev/event/DevReady.java deleted file mode 100644 index 0a754e0e..00000000 --- a/core/src/main/java/dev/streamx/cli/command/dev/event/DevReady.java +++ /dev/null @@ -1,5 +0,0 @@ -package dev.streamx.cli.command.dev.event; - -public class DevReady { - -} diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/ContainerWatcher.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/ContainerWatcher.java deleted file mode 100644 index 029014f1..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/ContainerWatcher.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static dev.streamx.cli.util.Output.print; - -import dev.streamx.runner.event.ContainerFailed; -import dev.streamx.runner.event.ContainerStarted; -import dev.streamx.runner.event.ContainerStopped; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; - -@ApplicationScoped -public class ContainerWatcher { - - void onContainerStarted(@Observes ContainerStarted event) { - print("🟢 " + event.getContainerName() + " ready."); - } - - void onContainerStopped(@Observes ContainerStopped event) { - print("🔴 " + event.getContainerName() + " stopped."); - } - - void onContainerFailed(@Observes ContainerFailed event) { - print("❌ " + event.getContainerName() + " failed."); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshConfig.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshConfig.java deleted file mode 100644 index 6077c535..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshConfig.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import io.smallrye.config.ConfigMapping; -import io.smallrye.config.WithName; -import java.util.Optional; - -@ConfigMapping -public interface MeshConfig { - - String STREAMX_MESH_PATH = "streamx.mesh-path"; - - @WithName(STREAMX_MESH_PATH) - Optional meshDefinitionFile(); -} diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolver.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolver.java deleted file mode 100644 index 92856e9e..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolver.java +++ /dev/null @@ -1,21 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import com.fasterxml.jackson.databind.ObjectMapper; -import dev.streamx.cli.interpolation.Interpolating; -import dev.streamx.mesh.model.ServiceMesh; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.io.IOException; -import java.nio.file.Path; - -@ApplicationScoped -public class MeshDefinitionResolver { - - @Inject - @Interpolating - ObjectMapper objectMapper; - - public ServiceMesh resolve(Path meshPath) throws IOException { - return objectMapper.readValue(meshPath.toFile(), ServiceMesh.class); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshManager.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshManager.java deleted file mode 100644 index 56ec249e..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshManager.java +++ /dev/null @@ -1,232 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static dev.streamx.cli.util.Output.print; -import static dev.streamx.runner.main.Main.StreamxApp.printSummary; - -import dev.streamx.cli.ExecutionExceptionHandler; -import dev.streamx.cli.command.run.RunningMeshPropertiesGenerator; -import dev.streamx.cli.exception.DockerException; -import dev.streamx.cli.util.ExceptionUtils; -import dev.streamx.mesh.model.ServiceMesh; -import dev.streamx.runner.StreamxRunner; -import dev.streamx.runner.event.MeshReloadUpdate; -import dev.streamx.runner.validation.excpetion.DockerContainerNonUniqueException; -import dev.streamx.runner.validation.excpetion.DockerEnvironmentException; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.concurrent.Callable; -import org.jetbrains.annotations.NotNull; -import picocli.CommandLine; - -@ApplicationScoped -public class MeshManager { - - @Inject - StreamxRunner runner; - - @Inject - MeshDefinitionResolver meshDefinitionResolver; - - @Inject - ExecutionExceptionHandler executionExceptionHandler; - - private ErrorHandlingExecutor errorHandlingExecutor; - private Path meshPath; - private String meshPathAsString; - private Path normalizedMeshPath; - private CommandLine commandLine; - private ServiceMesh serviceMesh; - private boolean firstStart = true; - - public void initializeMesh(Path meshPath) { - this.meshPath = meshPath; - this.normalizedMeshPath = meshPath.toAbsolutePath().normalize(); - this.meshPathAsString = normalizedMeshPath.toString(); - - this.serviceMesh = resolveMeshDefinition(meshPath);; - } - - public void initializeRunMode(Path meshPath) { - print("Setting up system containers..."); - this.errorHandlingExecutor = - new ErrorHandlingExecutor(false, executionExceptionHandler, commandLine); - - try { - this.runner.initialize(serviceMesh, meshPathAsString); - } catch (DockerContainerNonUniqueException e) { - throw DockerException.nonUniqueContainersException(e.getContainers()); - } catch (DockerEnvironmentException e) { - throw DockerException.dockerEnvironmentException(); - } catch (Exception e) { - throw throwMeshException(meshPath, e); - } - - this.runner.startBase(); - } - - public void initializeDevMode(Path meshPath, CommandLine commandLine) { - this.meshPath = meshPath; - this.errorHandlingExecutor = - new ErrorHandlingExecutor(true, executionExceptionHandler, commandLine); - this.commandLine = commandLine; - - normalizedMeshPath = meshPath.toAbsolutePath().normalize(); - meshPathAsString = normalizedMeshPath.toString(); - - print("\nSetting up system containers..."); - - this.runner.startBase(); - } - - public void start() { - if (firstStart) { - firstStart = false; - } - errorHandlingExecutor.execute(this::doStart); - } - - private void doStart() { - this.serviceMesh = resolveMeshDefinition(meshPath); - - try { - this.runner.initialize(serviceMesh, meshPathAsString); - } catch (DockerContainerNonUniqueException e) { - throw DockerException.nonUniqueContainersException(e.getContainers()); - } catch (DockerEnvironmentException e) { - throw DockerException.dockerEnvironmentException(); - } catch (Exception e) { - throw throwMeshException(meshPath, e); - } - - print(""); - print("Starting DX Mesh..."); - - boolean failFast = !errorHandlingExecutor.failsafe; - boolean started = this.runner.startMesh(failFast); - print(""); - RunningMeshPropertiesGenerator.generateRootAuthToken(this.runner.getMeshContext()); - if (started) { - printSummary(this.runner, normalizedMeshPath); - } - } - - @NotNull - private ServiceMesh resolveMeshDefinition(Path meshPath) { - try { - return meshDefinitionResolver.resolve(meshPath); - } catch (Exception e) { - throw throwMeshException(meshPath, e); - } - } - - private RuntimeException throwMeshException(Path meshPath, Exception e) { - return new RuntimeException( - ExceptionUtils.appendLogSuggestion( - "Unable to read mesh definition from '" + meshPath + "'.\n" - + "\n" - + "Details:\n" - + e.getMessage()), e); - } - - public void stop() { - this.serviceMesh = null; - doStop(); - } - - private void doStop() { - try { - print("Stopping DX Mesh..."); - - runner.stopMesh(); - - print("DX Mesh stopped..."); - print(""); - } catch (Exception e) { - if (!errorHandlingExecutor.failsafe) { - throw ExceptionUtils.sneakyThrow(e); - } - } - } - - public void reload() { - ServiceMesh newServiceMesh = errorHandlingExecutor.execute(() -> { - var serviceMesh = resolveMeshDefinition(meshPath); - serviceMesh.validate().assertValid(); - - return serviceMesh; - }); - - if (newServiceMesh == null) { - print("\nMesh definition is invalid. Skip reloading..."); - return; - } - - if (firstStart) { - firstStart = false; - start(); - } else { - try { - runner.reloadMesh(newServiceMesh); - serviceMesh = newServiceMesh; - } catch (Exception e) { - serviceMesh = null; - print("Mesh reload failed..."); - throw e; - } - } - } - - void onMeshStarted(@Observes MeshReloadUpdate event) { - switch (event.getEvent()) { - case MESH_UNCHANGED -> print("\nMesh definition is unchanged. Skip reloading..."); - case FULL_RELOAD_STARTED -> print("\nMesh file changed. Processing full reload..."); - case INCREMENTAL_RELOAD_STARTED -> - print("\nMesh file changed. Processing incremental reload..."); - case FULL_RELOAD_FINISHED, INCREMENTAL_RELOAD_FINISHED -> print("\nMesh reloaded."); - case FULL_RELOAD_FAILED, INCREMENTAL_RELOAD_FAILED -> print("\nMesh reload failed."); - default -> { } - } - } - - private static class ErrorHandlingExecutor { - - private final boolean failsafe; - private final ExecutionExceptionHandler executionExceptionHandler; - private final CommandLine commandLine; - - public ErrorHandlingExecutor(boolean failsafe, - ExecutionExceptionHandler executionExceptionHandler, CommandLine commandLine) { - this.failsafe = failsafe; - this.executionExceptionHandler = executionExceptionHandler; - this.commandLine = commandLine; - } - - private T execute(Callable callable) { - try { - return callable.call(); - } catch (Exception e) { - if (failsafe) { - executionExceptionHandler.handleExecutionException(e, commandLine); - - return null; - } else { - throw ExceptionUtils.sneakyThrow(e); - } - } - } - - private void execute(Runnable runnable) { - try { - runnable.run(); - } catch (Exception e) { - if (failsafe) { - executionExceptionHandler.handleExecutionException(e, commandLine); - } else { - throw ExceptionUtils.sneakyThrow(e); - } - } - } - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshResolver.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshResolver.java deleted file mode 100644 index ad1cef00..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshResolver.java +++ /dev/null @@ -1,67 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static dev.streamx.cli.util.Output.printf; - -import dev.streamx.cli.path.CurrentDirectoryProvider; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.Optional; -import org.jetbrains.annotations.NotNull; -import picocli.CommandLine; -import picocli.CommandLine.ParameterException; - -@ApplicationScoped -public class MeshResolver { - - public static final String MESH_YAML = "mesh.yaml"; - public static final String MESH_YML = "mesh.yml"; - - @Inject - CommandLine.ParseResult parseResult; - - @Inject - CurrentDirectoryProvider currentDirectoryProvider; - - @NotNull - public Path resolveMeshPath(MeshConfig meshConfig) { - return resolveMeshPath(meshConfig, true); - } - - @NotNull - public Path resolveMeshPath(MeshConfig meshConfig, boolean requireMeshExistence) { - return Optional.ofNullable(meshConfig) - .flatMap(MeshConfig::meshDefinitionFile) - .map(Path::of) - .orElseGet(() -> resolveCurrentDirectoryMeshPath(requireMeshExistence)); - } - - @NotNull - private Path resolveCurrentDirectoryMeshPath(boolean requireMeshExistence) { - String currentDirectory = currentDirectoryProvider.provide(); - Path pathToYaml = Path.of(currentDirectory, MESH_YAML); - Path pathToYml = Path.of(currentDirectory, MESH_YML); - - var yamlExists = pathToYaml.toFile().exists(); - var ymlExists = pathToYml.toFile().exists(); - - if (yamlExists && ymlExists) { - printf("Warning! Both '%s' and '%s' exist. Starting '%s' as it has higher priority.%n", - pathToYaml, pathToYml, pathToYaml); - } - - if (yamlExists) { - return pathToYaml; - } else if (ymlExists) { - return pathToYml; - } else if (requireMeshExistence) { - throw new ParameterException(parseResult.subcommand().commandSpec().commandLine(), - "Missing mesh definition. Use '-f' to select mesh file or " - + "make sure 'mesh.yaml' (or 'mesh.yml') exists in current directory."); - } else { - printf("Warning! Neither '%s' nor '%s' exist. Selecting '%s' as mesh file definition.%n", - pathToYaml, pathToYml, pathToYaml); - return pathToYaml; - } - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshSource.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshSource.java deleted file mode 100644 index 437fd025..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshSource.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import dev.streamx.cli.config.ArgumentConfigSource; -import picocli.CommandLine.Option; - -public class MeshSource { - - @Option(names = {"-f", "--file"}, paramLabel = "", - description = "Path to mesh definition file.") - void meshDefinitionFile(String meshDefinitionFile) { - ArgumentConfigSource.registerValue(MeshConfig.STREAMX_MESH_PATH, meshDefinitionFile); - } -} - diff --git a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshWatcher.java b/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshWatcher.java deleted file mode 100644 index 256d6839..00000000 --- a/core/src/main/java/dev/streamx/cli/command/meshprocessing/MeshWatcher.java +++ /dev/null @@ -1,111 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static dev.streamx.cli.util.Output.print; - -import io.quarkus.scheduler.Scheduled.ConcurrentExecution; -import io.quarkus.scheduler.Scheduler; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Path; -import java.nio.file.StandardWatchEventKinds; -import java.nio.file.WatchEvent; -import java.nio.file.WatchKey; -import java.nio.file.WatchService; -import org.jboss.logging.Logger; - -@ApplicationScoped -public class MeshWatcher { - - public static final String MESH_WATCHER_JOB_NAME = "meshWatcher"; - - @Inject - Logger log; - - @Inject - MeshManager meshManager; - - @Inject - Scheduler scheduler; - - public void watchMeshChanges(Path meshPath) { - try { - Path meshDir = meshPath.toAbsolutePath().normalize().getParent(); - - WatchService watchService = FileSystems.getDefault().newWatchService(); - WatchKey watchKey = meshDir.register(watchService, - StandardWatchEventKinds.ENTRY_CREATE, - StandardWatchEventKinds.ENTRY_MODIFY, - StandardWatchEventKinds.ENTRY_DELETE - ); - watchKey.reset(); - - scheduler.newJob(MESH_WATCHER_JOB_NAME) - .setConcurrentExecution(ConcurrentExecution.SKIP) - .setTask(task -> { - try { - ActionToPerform action = checkModifications(meshPath, watchService); - if (action != null) { - switch (action) { - case RELOAD -> { - meshManager.reload(); - } - case STOP -> { - print(""); - print("Mesh file deleted. Stopping..."); - meshManager.stop(); - print("Mesh stopped."); - } - default -> { - print("Unknown action: " + action + ". Skipping..."); - } - } - } - } catch (Exception e) { - log.error(e); - } - }) - .setInterval("500ms") - .schedule(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static ActionToPerform checkModifications(Path meshPath, WatchService watchService) { - ActionToPerform lastAction = null; - WatchKey polledKey = watchService.poll(); - if (polledKey != null) { - for (var event : polledKey.pollEvents()) { - if (pathsMatches(meshPath, event)) { - if (event.kind() == StandardWatchEventKinds.ENTRY_CREATE) { - lastAction = ActionToPerform.RELOAD; - } else if (event.kind() == StandardWatchEventKinds.ENTRY_MODIFY) { - lastAction = ActionToPerform.RELOAD; - } else if (event.kind() == StandardWatchEventKinds.ENTRY_DELETE) { - lastAction = ActionToPerform.STOP; - } - } - } - polledKey.reset(); - } - return lastAction; - } - - private enum ActionToPerform { - RELOAD, - STOP - } - - private static boolean pathsMatches(Path meshPath, WatchEvent event) { - Path modifiedFile = (Path) event.context(); - Path normalizedModifiedPath = meshPath.toAbsolutePath().normalize() - .getParent().resolve(modifiedFile) - .toAbsolutePath().normalize(); - - Path normalizedMeshPath = meshPath.toAbsolutePath().normalize(); - - return normalizedModifiedPath.equals(normalizedMeshPath); - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/run/RunCommand.java b/core/src/main/java/dev/streamx/cli/command/run/RunCommand.java deleted file mode 100644 index 345f1127..00000000 --- a/core/src/main/java/dev/streamx/cli/command/run/RunCommand.java +++ /dev/null @@ -1,62 +0,0 @@ -package dev.streamx.cli.command.run; - -import dev.streamx.cli.BannerPrinter; -import dev.streamx.cli.VersionProvider; -import dev.streamx.cli.command.meshprocessing.MeshConfig; -import dev.streamx.cli.command.meshprocessing.MeshManager; -import dev.streamx.cli.command.meshprocessing.MeshResolver; -import dev.streamx.cli.command.meshprocessing.MeshSource; -import dev.streamx.cli.exception.DockerException; -import dev.streamx.runner.StreamxRunner; -import dev.streamx.runner.exception.ContainerStartupTimeoutException; -import io.quarkus.runtime.Quarkus; -import jakarta.inject.Inject; -import java.nio.file.Path; -import picocli.CommandLine.ArgGroup; -import picocli.CommandLine.Command; - -@Command(name = RunCommand.COMMAND_NAME, - mixinStandardHelpOptions = true, - versionProvider = VersionProvider.class, - description = "Run a StreamX Mesh locally.") -public class RunCommand implements Runnable { - - public static final String COMMAND_NAME = "run"; - - @ArgGroup - MeshSource meshSource; - - @Inject - MeshConfig meshConfig; - - @Inject - MeshResolver meshResolver; - - @Inject - StreamxRunner runner; - - @Inject - BannerPrinter bannerPrinter; - - @Inject - MeshManager meshManager; - - @Override - public void run() { - try { - Path meshPath = meshResolver.resolveMeshPath(meshConfig); - meshManager.initializeMesh(meshPath); - - bannerPrinter.printBanner(); - meshManager.initializeRunMode(meshPath); - - meshManager.start(); - - Quarkus.waitForExit(); - } catch (ContainerStartupTimeoutException e) { - throw DockerException.containerStartupFailed( - e.getContainerName(), - runner.getContext().getStreamxBaseConfig().getContainerStartupTimeout()); - } - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/run/RunningMeshPropertiesGenerator.java b/core/src/main/java/dev/streamx/cli/command/run/RunningMeshPropertiesGenerator.java deleted file mode 100644 index 7d021ac2..00000000 --- a/core/src/main/java/dev/streamx/cli/command/run/RunningMeshPropertiesGenerator.java +++ /dev/null @@ -1,47 +0,0 @@ -package dev.streamx.cli.command.run; - -import static dev.streamx.cli.command.ingestion.IngestionClientConfig.STREAMX_INGESTION_AUTH_TOKEN; - -import dev.streamx.cli.config.DotStreamxGeneratedConfigSource; -import dev.streamx.runner.mesh.MeshContext; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.Map; -import java.util.Properties; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; - -public class RunningMeshPropertiesGenerator { - - private RunningMeshPropertiesGenerator() { - // no instance - } - - public static void generateRootAuthToken(MeshContext context) { - Map tokensBySource = context.getTokensBySource(); - if (tokensBySource != null) { - InputStream input = null; - OutputStream output = null; - try { - String streamxConfigPath = DotStreamxGeneratedConfigSource.getUrl().getPath(); - input = new FileInputStream(streamxConfigPath); - - Properties properties = new Properties(); - properties.load(input); - properties.setProperty(STREAMX_INGESTION_AUTH_TOKEN, tokensBySource.get("root")); - - output = new FileOutputStream(streamxConfigPath); - properties.store(output, null); - FileUtils.forceDeleteOnExit(DotStreamxGeneratedConfigSource.getConfigDir().toFile()); - } catch (IOException e) { - throw new RuntimeException("Failed to setup root authentication token", e); - } finally { - IOUtils.closeQuietly(input); - IOUtils.closeQuietly(output); - } - } - } -} diff --git a/core/src/main/java/dev/streamx/cli/command/run/TestContainerLogFilter.java b/core/src/main/java/dev/streamx/cli/command/run/TestContainerLogFilter.java deleted file mode 100644 index ad141a00..00000000 --- a/core/src/main/java/dev/streamx/cli/command/run/TestContainerLogFilter.java +++ /dev/null @@ -1,53 +0,0 @@ -package dev.streamx.cli.command.run; - - -import io.quarkus.logging.LoggingFilter; -import java.util.logging.Filter; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.stream.Stream; -import org.testcontainers.containers.ContainerLaunchException; - -@LoggingFilter(name = "tc-pull-filter") -public class TestContainerLogFilter implements Filter { - - private boolean skipLogsFromFailedContainer = false; - - @Override - public boolean isLoggable(LogRecord record) { - Level level = record.getLevel(); - - if (skipLogsFromFailedContainer(record)) { - return false; - } - - if (excludedExceptions(record)) { - skipLogsFromFailedContainer = true; - return false; - } - return isImagePullLog(record, level); - } - - private boolean skipLogsFromFailedContainer(LogRecord record) { - return skipLogsFromFailedContainer && record.getMessage() != null && record.getMessage() - .startsWith("Log output from the failed container"); - } - - private static boolean excludedExceptions(LogRecord record) { - if (record.getThrown() == null) { - return false; - } - return Stream.of(ContainerLaunchException.class) - .anyMatch(clazz -> clazz.isAssignableFrom(record.getThrown().getClass())); - } - - private static boolean isImagePullLog(LogRecord record, Level level) { - return level.intValue() >= Level.WARNING.intValue() || Stream.of( - "Pulling image", - "Pull complete.", - "Pulling docker image", - "Starting to pull image" - ) - .anyMatch(start -> record.getMessage().startsWith(start)); - } -} diff --git a/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesHelper.java b/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesHelper.java index aaa602fc..acefe43b 100644 --- a/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesHelper.java +++ b/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesHelper.java @@ -1,10 +1,10 @@ package dev.streamx.cli.config.validation; +import com.google.common.collect.HashMultimap; import jakarta.enterprise.context.ApplicationScoped; import org.eclipse.microprofile.config.ConfigProvider; import org.eclipse.microprofile.config.spi.ConfigSource; import org.jetbrains.annotations.NotNull; -import org.testcontainers.shaded.com.google.common.collect.HashMultimap; @ApplicationScoped class ConfigSourcesHelper { diff --git a/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesValidator.java b/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesValidator.java index c2d6d164..168d4308 100644 --- a/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesValidator.java +++ b/core/src/main/java/dev/streamx/cli/config/validation/ConfigSourcesValidator.java @@ -1,5 +1,6 @@ package dev.streamx.cli.config.validation; +import com.google.common.collect.HashMultimap; import dev.streamx.cli.exception.PropertiesException; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -7,7 +8,6 @@ import java.util.List; import org.eclipse.microprofile.config.spi.ConfigSource; import org.jetbrains.annotations.NotNull; -import org.testcontainers.shaded.com.google.common.collect.HashMultimap; @ApplicationScoped public class ConfigSourcesValidator { diff --git a/core/src/main/java/dev/streamx/cli/exception/DockerException.java b/core/src/main/java/dev/streamx/cli/exception/DockerException.java deleted file mode 100644 index cbfcd4ab..00000000 --- a/core/src/main/java/dev/streamx/cli/exception/DockerException.java +++ /dev/null @@ -1,115 +0,0 @@ -package dev.streamx.cli.exception; - -import dev.streamx.cli.util.ExceptionUtils; -import dev.streamx.runner.config.StreamxBaseConfig; -import dev.streamx.runner.validation.excpetion.DockerContainerNonUniqueException.ContainerStatus; -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import org.jetbrains.annotations.NotNull; -import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils; - -public class DockerException extends RuntimeException { - - private DockerException(String message, Exception exception) { - super(message, exception); - } - - private DockerException(String message) { - super(message); - } - - public static DockerException containerStartupFailed(String containerName, Long timeoutInSecs) { - return new DockerException(ExceptionUtils.appendLogSuggestion(""" - Timeout exceeded waiting for the container "%s" after %d seconds. - - Try increasing the timeout by setting the "%s" property.""" - .formatted(containerName, timeoutInSecs, - StreamxBaseConfig.PN_CONTAINER_STARTUP_TIMEOUT_SECONDS))); - } - - public static DockerException dockerEnvironmentException() { - return new DockerException(ExceptionUtils.appendLogSuggestion(""" - Could not find a valid Docker environment. - - Make sure that: - * Docker is installed, - * Docker is running""")); - } - - public static DockerException nonUniqueContainersException( - List containerStatus) { - Optional commonMesh = calculateCommonMeshForAllContainers(containerStatus); - - return commonMesh - .map(DockerException::nonUniqueContainersWithCommonMesh) - .orElseGet(() -> genericNonUniqueContainers(containerStatus)); - } - - @NotNull - private static DockerException genericNonUniqueContainers(List containerStatus) { - String conflictingContainersFragment = generateConflictingContainersFragment(containerStatus); - - String pluralMessageVersion = """ - StreamX tries to start Docker containers. It looks like - %s - names are already in use. \ - Remove or rename the containers with these names before restarting StreamX Mesh."""; - String singularMessageVersion = """ - StreamX tries to start Docker containers. It looks like - %s - name is already in use. \ - Remove or rename the container with this name before restarting StreamX Mesh."""; - - String template = containerStatus.size() > 1 - ? pluralMessageVersion - : singularMessageVersion; - return new DockerException(template.formatted(conflictingContainersFragment)); - } - - @NotNull - private static DockerException nonUniqueContainersWithCommonMesh(String commonMesh) { - String message = """ - It looks like some StreamX Mesh is already running. \ - Mesh definition: - %s - - Stop the running mesh \ - or remove containers of the running mesh before starting a new StreamX Mesh.""" - .formatted(commonMesh); - - return new DockerException(message); - } - - @NotNull - private static Optional calculateCommonMeshForAllContainers( - List containerStatus) { - boolean allNonuniqueContainersAreFromMesh = containerStatus.stream() - .allMatch(cs -> StringUtils.isNotBlank(cs.meshPath())); - - Set meshNames = containerStatus.stream() - .map(ContainerStatus::meshPath) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - if (allNonuniqueContainersAreFromMesh && meshNames.size() == 1) { - return meshNames.stream().findFirst(); - } - return Optional.empty(); - } - - @NotNull - private static String generateConflictingContainersFragment( - List containerStatus) { - return containerStatus.stream() - .map(cs -> " * " + removeSlashPrefix(cs.name())) - .collect(Collectors.joining("\n")); - } - - @NotNull - private static String removeSlashPrefix(String cs) { - return cs.startsWith("/") ? cs.substring(1) : cs; - } -} diff --git a/core/src/test/java/dev/streamx/cli/OsUtils.java b/core/src/test/java/dev/streamx/cli/OsUtils.java index 924bdb84..a6b79c8f 100644 --- a/core/src/test/java/dev/streamx/cli/OsUtils.java +++ b/core/src/test/java/dev/streamx/cli/OsUtils.java @@ -1,18 +1,8 @@ package dev.streamx.cli; -import dev.streamx.runner.validation.DockerEnvironmentValidator; import org.apache.commons.lang3.StringEscapeUtils; public class OsUtils { public static final String ESCAPED_LINE_SEPARATOR = StringEscapeUtils.escapeJson(System.lineSeparator()); - - public static boolean isDockerAvailable() { - try { - new DockerEnvironmentValidator().validateDockerClient(); - return true; - } catch (Exception e) { - return false; - } - } } diff --git a/core/src/test/java/dev/streamx/cli/command/MeshStopper.java b/core/src/test/java/dev/streamx/cli/command/MeshStopper.java deleted file mode 100644 index d3660c7b..00000000 --- a/core/src/test/java/dev/streamx/cli/command/MeshStopper.java +++ /dev/null @@ -1,32 +0,0 @@ -package dev.streamx.cli.command; - -import dev.streamx.runner.StreamxRunner; -import io.quarkus.runtime.ApplicationLifecycleManager; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.inject.Inject; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -@ApplicationScoped -public class MeshStopper { - - private static final ScheduledExecutorService SCHEDULER = - Executors.newSingleThreadScheduledExecutor(); - private static final AtomicBoolean scheduled = new AtomicBoolean(false); - - @Inject - StreamxRunner streamxRunner; - - public void scheduleStop() { - if (!scheduled.getAndSet(true)) { - SCHEDULER.schedule(() -> { - streamxRunner.stopMesh(); - streamxRunner.stopBase(); - - ApplicationLifecycleManager.exit(); - }, 100, TimeUnit.MILLISECONDS); - } - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/ConfigurationInterpolationTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/ConfigurationInterpolationTest.java deleted file mode 100644 index 96c18c15..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/ConfigurationInterpolationTest.java +++ /dev/null @@ -1,95 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; - -import com.fasterxml.jackson.databind.exc.InvalidFormatException; -import dev.streamx.operator.crd.ServiceMesh; -import io.quarkus.test.junit.QuarkusTest; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.NoSuchElementException; -import java.util.Set; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; - -@QuarkusTest -class ConfigurationInterpolationTest { - - @Inject - ServiceMeshResolver cut; - - @AfterEach - void cleanup() { - var propertiesToClear = Set.of( - "string.array.property", "string.property", "integer.property", "boolean.property"); - - propertiesToClear.forEach(System::clearProperty); - } - - @Test - void shouldConfigurationBeInterpolatedFromProperties() { - // Three properties overriding application.properties values - System.setProperty("string.array.property", "stringArrayValue"); - System.setProperty("string.property", "stringValue"); - System.setProperty("integer.property", "0"); - // One extra property - System.setProperty("boolean.property", "true"); - - Path meshPath = ProjectUtils.getResourcePath(Path.of("configuration-interpolation.yaml")); - ServiceMesh serviceMesh = cut.resolveMesh(meshPath); - - assertThat(serviceMesh.getSpec().getSources().get("cli").getOutgoing().get(0)) - .isEqualTo("stringArrayValue"); - assertThat(serviceMesh.getSpec().getProcessing().get("relay").getImage()) - .isEqualTo("stringValue"); - assertThat(serviceMesh.getSpec().getDeploymentConfig().getDelivery() - .get("web-delivery-service").getReplicas()).isEqualTo(0); - assertThat(serviceMesh.getSpec().getDeploymentConfig().getDelivery() - .get("web-delivery-service").isStateful()).isTrue(); - } - - @Test - void shouldConfigurationBeInterpolatedFromFile() { - // Three properties comes from application.properties - System.clearProperty("string.array.property"); - System.clearProperty("string.property"); - System.clearProperty("integer.property"); - // This one is declared only to let the mesh load - System.setProperty("boolean.property", "true"); - - Path meshPath = ProjectUtils.getResourcePath(Path.of("configuration-interpolation.yaml")); - ServiceMesh serviceMesh = cut.resolveMesh(meshPath); - - assertThat(serviceMesh.getSpec().getSources().get("cli").getOutgoing().get(0)) - .isEqualTo("stringArrayValueFromFile"); - assertThat(serviceMesh.getSpec().getProcessing().get("relay").getImage()) - .isEqualTo("stringValueFromFile"); - assertThat(serviceMesh.getSpec().getDeploymentConfig().getDelivery() - .get("web-delivery-service").getReplicas()).isEqualTo(1); - } - - @Test - void shouldConfigurationInterpolationFailOnMissingProperty() { - System.clearProperty("boolean.property"); - - final Path meshPath = ProjectUtils - .getResourcePath(Path.of("configuration-interpolation.yaml")); - - RuntimeException ex = assertThrowsExactly(RuntimeException.class, - () -> cut.resolveMesh(meshPath)); - assertThat(ex).hasRootCauseExactlyInstanceOf(NoSuchElementException.class); - } - - @Test - void shouldConfigurationInterpolationFailOnWrongType() { - System.setProperty("boolean.property", "10"); - - final Path meshPath = ProjectUtils - .getResourcePath(Path.of("configuration-interpolation.yaml")); - - RuntimeException ex = assertThrowsExactly(RuntimeException.class, - () -> cut.resolveMesh(meshPath)); - assertThat(ex).hasRootCauseExactlyInstanceOf(InvalidFormatException.class); - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/ProjectPathsResolverTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/ProjectPathsResolverTest.java deleted file mode 100644 index 89d84431..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/ProjectPathsResolverTest.java +++ /dev/null @@ -1,41 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.quarkus.test.component.QuarkusComponentTest; -import jakarta.inject.Inject; -import java.nio.file.Path; -import org.junit.jupiter.api.Test; - -@QuarkusComponentTest -class ProjectPathsResolverTest { - - @Inject - ProjectPathsResolver cut; - - @Test - void shouldReturnDefaultDeploymentPath() { - Path deploymentPath = cut.resolveDeploymentPath( - ProjectUtils.getResourcePath(Path.of("mesh.yaml"))); - assertThat(deploymentPath).endsWith(Path.of("deployment.yaml")); - } - - @Test - void shouldReturnCustomDeploymentPath() { - Path deploymentPath = cut.resolveDeploymentPath( - ProjectUtils.getResourcePath(Path.of("custom-name.yaml"))); - assertThat(deploymentPath).endsWith(Path.of("deployment.custom-name.yaml")); - } - - @Test - void shouldReturnSecretPath() { - Path secretPath = cut.resolveSecretPath(ProjectUtils.getProjectPath(), "global.properties"); - assertThat(secretPath).endsWith(Path.of("project", "secrets", "global.properties")); - } - - @Test - void shouldReturnConfigPath() { - Path secretPath = cut.resolveConfigPath(ProjectUtils.getProjectPath(), "global.properties"); - assertThat(secretPath).endsWith(Path.of("project", "configs", "global.properties")); - } -} \ No newline at end of file diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/ProjectUtils.java b/core/src/test/java/dev/streamx/cli/command/cloud/ProjectUtils.java deleted file mode 100644 index d19abe8c..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/ProjectUtils.java +++ /dev/null @@ -1,33 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URISyntaxException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Path; -import java.nio.file.Paths; - -public final class ProjectUtils { - - private static final String PROJECT_PATH = "project/"; - - public static Path getResourcePath(Path resourcePath) { - return getProjectPath().resolve(resourcePath); - } - - public static Path getProjectPath() { - try { - return Paths.get(ProjectUtils.class.getResource(PROJECT_PATH).toURI()); - } catch (URISyntaxException e) { - throw new RuntimeException("Could not map project path to URI", e); - } - } - - public static String getResource(String resourceName) throws IOException { - try (InputStream is = ServiceMeshResolverTest.class.getResourceAsStream( - PROJECT_PATH + resourceName)) { - return new String(is.readAllBytes(), StandardCharsets.UTF_8) - .replace("\r\n", "\n"); - } - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/ServiceMeshCrdProvider.java b/core/src/test/java/dev/streamx/cli/command/cloud/ServiceMeshCrdProvider.java deleted file mode 100644 index 09418cce..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/ServiceMeshCrdProvider.java +++ /dev/null @@ -1,25 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import dev.streamx.cli.command.cloud.deploy.DeployCommandIT; -import io.fabric8.kubernetes.client.KubernetesClient; -import io.fabric8.kubernetes.client.dsl.NonDeletingOperation; -import io.quarkus.arc.properties.IfBuildProperty; -import io.quarkus.runtime.StartupEvent; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; - -@ApplicationScoped -@IfBuildProperty(name = "%test.quarkus.kubernetes-client.devservices.enabled", - stringValue = "true") -public class ServiceMeshCrdProvider { - - @Inject - KubernetesClient kubernetesClient; - - void onStart(@Observes StartupEvent ev) { - kubernetesClient.apiextensions().v1().customResourceDefinitions() - .load(DeployCommandIT.class.getResourceAsStream("servicemeshes.streamx.dev-v1.yml")) - .createOr(NonDeletingOperation::update); - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/ServiceMeshResolverTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/ServiceMeshResolverTest.java deleted file mode 100644 index d79e92f7..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/ServiceMeshResolverTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package dev.streamx.cli.command.cloud; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import dev.streamx.cli.command.cloud.ServiceMeshResolver.ConfigSourcesPaths; -import dev.streamx.cli.interpolation.Interpolating; -import dev.streamx.mesh.model.AbstractContainer; -import dev.streamx.operator.crd.ServiceMesh; -import dev.streamx.operator.crd.deployment.ServiceMeshDeploymentConfig; -import io.quarkus.test.junit.QuarkusTest; -import jakarta.inject.Inject; -import java.io.IOException; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; - -@QuarkusTest -class ServiceMeshResolverTest { - - @Inject - ServiceMeshResolver cut; - @Inject - @Interpolating - ObjectMapper objectMapper; - - - @Test - void shouldThrowExceptionForEmptyMeshFile() { - Path meshPath = ProjectUtils.getResourcePath(Path.of("empty-mesh.yaml")); - RuntimeException runtimeException = assertThrowsExactly(RuntimeException.class, - () -> cut.resolveMesh(meshPath)); - assertThat(runtimeException.getMessage()).isEqualTo( - "Mesh file with provided path '" + meshPath + "' is empty."); - } - - @Test - void shouldReturnServiceMeshWithDefaultDeploymentName() throws IOException { - ServiceMesh serviceMesh = getServiceMesh("mesh.yaml"); - assertNotNull(serviceMesh); - String deploymentConfigYaml = mapDeploymentConfigToYaml(serviceMesh); - String expected = ProjectUtils.getResource("deployment.yaml"); - assertEquals(expected, deploymentConfigYaml); - } - - @Test - void shouldReturnServiceMeshWithCustomDeploymentName() throws IOException { - ServiceMesh serviceMesh = getServiceMesh("custom-name.yaml"); - assertNotNull(serviceMesh); - String deploymentConfigYaml = mapDeploymentConfigToYaml(serviceMesh); - String expected = ProjectUtils.getResource("deployment.custom-name.yaml"); - assertEquals(expected, deploymentConfigYaml); - } - - @Test - void shouldReturnServiceMeshWithoutDeployment() { - ServiceMesh serviceMesh = getServiceMesh("nodeployment.yaml"); - assertNotNull(serviceMesh); - assertNull(serviceMesh.getSpec().getDeploymentConfig()); - } - - @Test - void shouldReturnMessageAboutInvalidMeshPath() { - RuntimeException runtimeException = assertThrowsExactly(RuntimeException.class, - () -> cut.resolveMesh(Path.of("nonexisting.mesh.yaml"))); - assertEquals("Mesh file with provided path 'nonexisting.mesh.yaml' does not exist.", - runtimeException.getMessage()); - } - - @Test - void shouldReturnAllConfigurableContainers() { - ServiceMesh serviceMesh = getServiceMesh("with-configs.yaml"); - List containers = cut.extractContainers(serviceMesh); - assertEquals(4, containers.size()); - } - - @Test - void shouldReturnAllConfigSourcesPaths() { - ServiceMesh serviceMesh = getServiceMesh("with-configs.yaml"); - ConfigSourcesPaths configSourcesPaths = cut.extractConfigSourcesPaths(serviceMesh); - Set expectedEnvsPaths = Set.of( - "global.properties", - "ingestion/rest.properties", - "processing/relay.properties", - "delivery/wds.properties", - "delivery/wds/nginx.properties", - "shared.properties" - ); - assertThat(configSourcesPaths.configEnvPaths()).containsExactlyInAnyOrderElementsOf( - expectedEnvsPaths); - assertThat(configSourcesPaths.secretEnvPaths()).containsExactlyInAnyOrderElementsOf( - expectedEnvsPaths); - Set expectedVolumesPaths = Set.of( - "ingestion/rest/file.txt", - "processing/relay/file.txt", - "delivery/wds/file.txt", - "delivery/wds/dir", - "delivery/wds/nginx/file.txt", - "shared" - ); - assertThat(configSourcesPaths.configVolumePaths()).containsExactlyInAnyOrderElementsOf( - expectedVolumesPaths); - assertThat(configSourcesPaths.secretVolumePaths()).containsExactlyInAnyOrderElementsOf( - expectedVolumesPaths); - } - - @Test - void shouldMapEmptyDeploymentFileToNull() { - Path meshPath = ProjectUtils.getResourcePath(Path.of("empty-deployment.yaml")); - ServiceMesh serviceMesh = cut.resolveMesh(meshPath); - assertThat(serviceMesh.getSpec().getDeploymentConfig()).isNull(); - } - - @NotNull - private ServiceMesh getServiceMesh(String meshName) { - Path meshPath = ProjectUtils.getResourcePath(Path.of(meshName)); - return cut.resolveMesh(meshPath); - } - - @NotNull - private String mapDeploymentConfigToYaml(ServiceMesh serviceMesh) throws JsonProcessingException { - ServiceMeshDeploymentConfig deploymentConfig = serviceMesh.getSpec().getDeploymentConfig(); - return objectMapper.writeValueAsString(deploymentConfig); - } -} \ No newline at end of file diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/ConfigServiceTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/deploy/ConfigServiceTest.java deleted file mode 100644 index da445a2f..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/ConfigServiceTest.java +++ /dev/null @@ -1,132 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.mockito.Mockito.when; - -import dev.streamx.cli.command.cloud.ProjectPathsResolver; -import dev.streamx.cli.command.cloud.ProjectUtils; -import dev.streamx.cli.command.cloud.deploy.Config.ConfigType; -import io.quarkus.test.InjectMock; -import io.quarkus.test.component.QuarkusComponentTest; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.Map; -import org.junit.jupiter.api.Test; - -@QuarkusComponentTest -class ConfigServiceTest { - - @Inject - ConfigService cut; - - @InjectMock - ProjectPathsResolver projectPathsResolver; - - @InjectMock - DataService dataService; - - @Test - void shouldReturnDirType() { - ConfigType configType = cut.getConfigType( - ProjectUtils.getResourcePath(Path.of("configs", "shared"))); - assertEquals(ConfigType.DIR, configType); - } - - @Test - void shouldReturnFileType() { - ConfigType configType = cut.getConfigType( - ProjectUtils.getResourcePath(Path.of("configs", "global.properties"))); - assertEquals(ConfigType.FILE, configType); - } - - @Test - void shouldReturnCorrectLabelValue() { - assertEquals("file", ConfigType.FILE.getLabelValue()); - assertEquals("dir", ConfigType.DIR.getLabelValue()); - } - - @Test - void shouldReturnEnvConfig() { - Path projectPath = ProjectUtils.getProjectPath(); - String configName = "global.properties"; - Path configPath = ProjectUtils.getResourcePath(Path.of("configs", configName)); - when(projectPathsResolver.resolveConfigPath(projectPath, configName)).thenReturn(configPath); - Map data = Map.of("key", "value"); - when(dataService.loadDataFromProperties(configPath)).thenReturn(data); - Config configEnv = cut.getConfigEnv(projectPath, configName); - assertEquals(configEnv.name(), configName); - assertEquals(configEnv.data(), data); - assertEquals(configEnv.configType(), ConfigType.FILE); - } - - @Test - void shouldReturnSecretEnvConfig() { - Path projectPath = ProjectUtils.getProjectPath(); - String configName = "shared.properties"; - Path configPath = ProjectUtils.getResourcePath(Path.of("secrets", configName)); - when(projectPathsResolver.resolveSecretPath(projectPath, configName)).thenReturn(configPath); - Map data = Map.of("secretKey", "secretValue"); - when(dataService.loadDataFromProperties(configPath)).thenReturn(data); - Config configEnv = cut.getSecretEnv(projectPath, configName); - assertEquals(configEnv.name(), configName); - assertEquals(configEnv.data(), data); - assertEquals(configEnv.configType(), ConfigType.FILE); - } - - @Test - void shouldReturnFileVolumeConfig() { - Path projectPath = ProjectUtils.getProjectPath(); - String configName = "delivery/wds/file.txt"; - Path configPath = ProjectUtils.getResourcePath(Path.of("configs", configName)); - when(projectPathsResolver.resolveConfigPath(projectPath, configName)).thenReturn(configPath); - Map data = Map.of("file.txt", "File content"); - when(dataService.loadDataFromFiles(configPath)).thenReturn(data); - Config configEnv = cut.getConfigVolume(projectPath, configName); - assertEquals(configEnv.name(), configName); - assertEquals(configEnv.data(), data); - assertEquals(configEnv.configType(), ConfigType.FILE); - } - - @Test - void shouldReturnDirVolumeConfig() { - Path projectPath = ProjectUtils.getProjectPath(); - String configName = "delivery/wds/dir"; - Path configPath = ProjectUtils.getResourcePath(Path.of("configs", configName)); - when(projectPathsResolver.resolveConfigPath(projectPath, configName)).thenReturn(configPath); - Map data = Map.of("file.txt", "File content", "file1.txt", "File1 content"); - when(dataService.loadDataFromFiles(configPath)).thenReturn(data); - Config configEnv = cut.getConfigVolume(projectPath, configName); - assertEquals(configEnv.name(), configName); - assertEquals(configEnv.data(), data); - assertEquals(configEnv.configType(), ConfigType.DIR); - } - - @Test - void shouldReturnSecretFileVolumeConfig() { - Path projectPath = ProjectUtils.getProjectPath(); - String configName = "delivery/wds/file.txt"; - Path configPath = ProjectUtils.getResourcePath(Path.of("secrets", configName)); - when(projectPathsResolver.resolveSecretPath(projectPath, configName)).thenReturn(configPath); - Map data = Map.of("secret-file.txt", "File content"); - when(dataService.loadDataFromFiles(configPath)).thenReturn(data); - Config configEnv = cut.getSecretVolume(projectPath, configName); - assertEquals(configEnv.name(), configName); - assertEquals(configEnv.data(), data); - assertEquals(configEnv.configType(), ConfigType.FILE); - } - - @Test - void shouldReturnSecretDirVolumeConfig() { - Path projectPath = ProjectUtils.getProjectPath(); - String configName = "delivery/wds/dir"; - Path configPath = ProjectUtils.getResourcePath(Path.of("secrets", configName)); - when(projectPathsResolver.resolveSecretPath(projectPath, configName)).thenReturn(configPath); - Map data = Map.of("secret-file.txt", "File content", "secret-file1.txt", - "File1 content"); - when(dataService.loadDataFromFiles(configPath)).thenReturn(data); - Config configEnv = cut.getSecretVolume(projectPath, configName); - assertEquals(configEnv.name(), configName); - assertEquals(configEnv.data(), data); - assertEquals(configEnv.configType(), ConfigType.DIR); - } -} \ No newline at end of file diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/DataServiceTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/deploy/DataServiceTest.java deleted file mode 100644 index 743ed928..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/DataServiceTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; - -import dev.streamx.cli.command.cloud.ProjectUtils; -import java.nio.file.Path; -import java.util.Map; -import org.junit.jupiter.api.Test; - -class DataServiceTest { - - DataService cut = new DataService(); - - @Test - void shouldReturnDataWithAllProperties() { - Path propertiesPath = ProjectUtils.getResourcePath(Path.of("configs", "global.properties")); - Map data = cut.loadDataFromProperties(propertiesPath); - Map expectedProperties = Map.of( - "CONFIG_GLOBAL_PROP_NAME", "config-global-prop-value", - "CONFIG_GLOBAL_ANOTHER_PROP_NAME", "config-global-another-prop-value"); - assertThat(data).containsExactlyInAnyOrderEntriesOf(expectedProperties); - } - - @Test - void shouldThrowExceptionAboutInvalidPropertiesFile() { - Path propertiesPath = ProjectUtils.getResourcePath( - Path.of("configs", "nonexistent.properties")); - RuntimeException nonexistentFileException = assertThrowsExactly(IllegalStateException.class, - () -> cut.loadDataFromProperties(propertiesPath)); - assertThat(nonexistentFileException.getMessage()).isEqualTo("Path " + propertiesPath - + " provided in Mesh must be a valid properties file."); - Path dirPath = ProjectUtils.getResourcePath(Path.of("configs")); - RuntimeException dirIsNotValidPropertiesFileException = assertThrowsExactly( - IllegalStateException.class, () -> cut.loadDataFromProperties(dirPath)); - assertThat(dirIsNotValidPropertiesFileException.getMessage()).isEqualTo("Path " + dirPath - + " provided in Mesh must be a valid properties file."); - } - - @Test - void shouldThrowExceptionAboutInvalidPropertyKey() { - Path propertiesPath = ProjectUtils.getResourcePath( - Path.of("configs", "invalid", "invalid_prop_key.properties")); - RuntimeException nonexistentFileException = assertThrowsExactly(IllegalArgumentException.class, - () -> cut.loadDataFromProperties(propertiesPath)); - assertThat(nonexistentFileException.getMessage()).isEqualTo( - "Invalid properties key: invalid[]key in environmentFrom: " + propertiesPath - + ". Valid property key must consist of alphanumeric characters, '-', '_' or '.'."); - } - - @Test - void shouldThrowExceptionAboutInvalidFileName() { - Path configPath = ProjectUtils.getResourcePath( - Path.of("configs", "invalid", "invalid[]name.txt")); - RuntimeException nonexistentFileException = assertThrowsExactly(IllegalArgumentException.class, - () -> cut.loadDataFromFiles(configPath)); - assertThat(nonexistentFileException.getMessage()).isEqualTo( - "Invalid file name: invalid[]name.txt in volumesFrom: " + configPath - + ". Valid file name must consist of alphanumeric characters, '-', '_' or '.'."); - } - - @Test - void shouldThrowExceptionAboutInvalidFileNameInDir() { - Path configPath = ProjectUtils.getResourcePath( - Path.of("configs", "invalid")); - RuntimeException nonexistentFileException = assertThrowsExactly(IllegalArgumentException.class, - () -> cut.loadDataFromFiles(configPath)); - assertThat(nonexistentFileException.getMessage()).isEqualTo( - "Invalid file name: invalid[]name.txt in volumesFrom: " + configPath - + ". Valid file name must consist of alphanumeric characters, '-', '_' or '.'."); - } - - @Test - void shouldReturnDataMatchingFileContent() { - Path propertiesPath = ProjectUtils.getResourcePath(Path.of("configs", "shared", "file.txt")); - Map data = cut.loadDataFromFiles(propertiesPath); - Map expectedData = Map.of("file.txt", "shared/file.txt"); - assertThat(data).containsExactlyInAnyOrderEntriesOf(expectedData); - } - - @Test - void shouldReturnDataMatchingDirContent() { - Path propertiesPath = ProjectUtils.getResourcePath(Path.of("configs", "shared")); - Map data = cut.loadDataFromFiles(propertiesPath); - Map expectedData = Map.of( - "file.txt", "shared/file.txt", - "file1.txt", "shared/file1.txt"); - assertThat(data).containsExactlyInAnyOrderEntriesOf(expectedData); - } -} \ No newline at end of file diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/DeployCommandIT.java b/core/src/test/java/dev/streamx/cli/command/cloud/deploy/DeployCommandIT.java deleted file mode 100644 index adece73c..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/DeployCommandIT.java +++ /dev/null @@ -1,27 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import static org.assertj.core.api.Assertions.assertThat; - -import dev.streamx.cli.command.cloud.KubernetesClientProfile; -import dev.streamx.cli.command.cloud.ProjectUtils; -import io.quarkus.test.junit.TestProfile; -import io.quarkus.test.junit.main.LaunchResult; -import io.quarkus.test.junit.main.QuarkusMainLauncher; -import io.quarkus.test.junit.main.QuarkusMainTest; -import java.nio.file.Path; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; - -@QuarkusMainTest -@EnabledIf("dev.streamx.cli.OsUtils#isDockerAvailable") -@TestProfile(KubernetesClientProfile.class) -public class DeployCommandIT { - - @Test - void shouldDeployProject(QuarkusMainLauncher launcher) { - String meshPath = ProjectUtils.getResourcePath(Path.of("with-configs.yaml")).toString(); - LaunchResult result = launcher.launch("deploy", "-f=" + meshPath); - assertThat(result.getOutput()).contains("successfully deployed to 'default' namespace."); - } - -} diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/KubernetesServiceTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/deploy/KubernetesServiceTest.java deleted file mode 100644 index df4aa5f3..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/KubernetesServiceTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import static dev.streamx.cli.command.cloud.MetadataUtils.COMPONENT_LABEL; -import static dev.streamx.cli.command.cloud.MetadataUtils.CONFIG_TYPE_LABEL; -import static dev.streamx.cli.command.cloud.MetadataUtils.INSTANCE_LABEL; -import static dev.streamx.cli.command.cloud.MetadataUtils.MANAGED_BY_LABEL; -import static dev.streamx.cli.command.cloud.MetadataUtils.MANAGED_BY_LABEL_VALUE; -import static dev.streamx.cli.command.cloud.MetadataUtils.NAME_LABEL; -import static dev.streamx.cli.command.cloud.MetadataUtils.PART_OF_LABEL; -import static org.assertj.core.api.Assertions.assertThat; - -import dev.streamx.cli.command.cloud.KubernetesService; -import dev.streamx.cli.command.cloud.deploy.Config.ConfigType; -import dev.streamx.operator.Component; -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.ObjectMeta; -import io.fabric8.kubernetes.api.model.Secret; -import io.quarkus.test.component.QuarkusComponentTest; -import jakarta.inject.Inject; -import java.util.Map; -import org.junit.jupiter.api.Test; - -@QuarkusComponentTest -class KubernetesServiceTest { - - private static final String MESH_NAME = "sx"; - @Inject - KubernetesService cut; - - @Test - void shouldReturnConfigMapWithRequiredMetadataAndData() { - Map data = Map.of("key", "value"); - ConfigType configType = ConfigType.FILE; - Config config = new Config("test/default.conf", data, configType); - ConfigMap configMap = cut.buildConfigMap(MESH_NAME, config); - ObjectMeta metadata = configMap.getMetadata(); - assertThat(metadata.getName()).isEqualTo("sx-extcfg-test-default-conf"); - Map expectedLabels = Map.of( - NAME_LABEL, "test-default-conf", - INSTANCE_LABEL, "sx-extcfg-test-default-conf", - COMPONENT_LABEL, Component.EXTERNAL_CONFIG.getName(), - MANAGED_BY_LABEL, MANAGED_BY_LABEL_VALUE, - CONFIG_TYPE_LABEL, configType.getLabelValue(), - PART_OF_LABEL, "sx" - ); - assertThat(metadata.getLabels()).containsExactlyInAnyOrderEntriesOf(expectedLabels); - assertThat(configMap.getData()).containsExactlyInAnyOrderEntriesOf(data); - } - - @Test - void shouldReturnSecretWithRequiredMetadataAndData() { - ConfigType configType = ConfigType.DIR; - Map data = Map.of("key", "value"); - Config config = new Config("test/default.conf", data, configType); - Secret secret = cut.buildSecret(MESH_NAME, config); - ObjectMeta metadata = secret.getMetadata(); - assertThat(metadata.getName()).isEqualTo("sx-extsec-test-default-conf"); - Map expectedLabels = Map.of( - NAME_LABEL, "test-default-conf", - INSTANCE_LABEL, "sx-extsec-test-default-conf", - COMPONENT_LABEL, Component.EXTERNAL_SECRET.getName(), - MANAGED_BY_LABEL, MANAGED_BY_LABEL_VALUE, - CONFIG_TYPE_LABEL, configType.getLabelValue(), - PART_OF_LABEL, "sx" - ); - assertThat(metadata.getLabels()).containsExactlyInAnyOrderEntriesOf(expectedLabels); - assertThat(secret.getStringData()).containsExactlyInAnyOrderEntriesOf(data); - } -} \ No newline at end of file diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/ProjectResourcesExtractorTest.java b/core/src/test/java/dev/streamx/cli/command/cloud/deploy/ProjectResourcesExtractorTest.java deleted file mode 100644 index 1dcca3a6..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/deploy/ProjectResourcesExtractorTest.java +++ /dev/null @@ -1,70 +0,0 @@ -package dev.streamx.cli.command.cloud.deploy; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import dev.streamx.cli.command.cloud.KubernetesService; -import dev.streamx.cli.command.cloud.ProjectUtils; -import dev.streamx.cli.command.cloud.ServiceMeshResolver.ConfigSourcesPaths; -import dev.streamx.cli.command.cloud.deploy.Config.ConfigType; -import io.fabric8.kubernetes.api.model.ConfigMap; -import io.fabric8.kubernetes.api.model.Secret; -import io.quarkus.test.InjectMock; -import io.quarkus.test.component.QuarkusComponentTest; -import jakarta.inject.Inject; -import java.nio.file.Path; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Set; -import org.junit.jupiter.api.Test; - -@QuarkusComponentTest -class ProjectResourcesExtractorTest { - - @InjectMock - ConfigService configService; - - @InjectMock - KubernetesService kubernetesService; - - @Inject - ProjectResourcesExtractor projectResourcesExtractor; - - @Test - void shouldReturnExtractedConfigMaps() { - String meshName = "sx"; - Path projectPath = ProjectUtils.getProjectPath(); - ConfigSourcesPaths configSourcesPaths = new ConfigSourcesPaths( - Set.of("global.properties"), - Collections.emptySet(), - Set.of("shared/file.txt"), - Collections.emptySet()); - Config config = new Config("name", Map.of("key", "value"), ConfigType.FILE); - when(configService.getConfigEnv(projectPath, "global.properties")).thenReturn(config); - when(configService.getConfigVolume(projectPath, "shared/file.txt")).thenReturn(config); - when(kubernetesService.buildConfigMap(meshName, config)).thenReturn(mock(ConfigMap.class)); - List configMaps = projectResourcesExtractor.getConfigMaps(projectPath, - configSourcesPaths, meshName); - assertThat(configMaps).hasSize(2); - } - - @Test - void shouldReturnExtractedSecrets() { - String meshName = "sx"; - Path projectPath = ProjectUtils.getProjectPath(); - ConfigSourcesPaths configSourcesPaths = new ConfigSourcesPaths( - Collections.emptySet(), - Set.of("global.properties"), - Collections.emptySet(), - Set.of("shared/file.txt")); - Config config = new Config("name", Map.of("key", "value"), ConfigType.FILE); - when(configService.getSecretEnv(projectPath, "global.properties")).thenReturn(config); - when(configService.getSecretVolume(projectPath, "shared/file.txt")).thenReturn(config); - when(kubernetesService.buildSecret(meshName, config)).thenReturn(mock(Secret.class)); - List secrets = projectResourcesExtractor.getSecrets(projectPath, - configSourcesPaths, meshName); - assertThat(secrets).hasSize(2); - } -} \ No newline at end of file diff --git a/core/src/test/java/dev/streamx/cli/command/cloud/undeploy/UndeployCommandIT.java b/core/src/test/java/dev/streamx/cli/command/cloud/undeploy/UndeployCommandIT.java deleted file mode 100644 index 7b7d13fe..00000000 --- a/core/src/test/java/dev/streamx/cli/command/cloud/undeploy/UndeployCommandIT.java +++ /dev/null @@ -1,24 +0,0 @@ -package dev.streamx.cli.command.cloud.undeploy; - -import static org.assertj.core.api.Assertions.assertThat; - -import dev.streamx.cli.command.cloud.KubernetesClientProfile; -import io.quarkus.test.junit.TestProfile; -import io.quarkus.test.junit.main.LaunchResult; -import io.quarkus.test.junit.main.QuarkusMainLauncher; -import io.quarkus.test.junit.main.QuarkusMainTest; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; - -@QuarkusMainTest -@EnabledIf("dev.streamx.cli.OsUtils#isDockerAvailable") -@TestProfile(KubernetesClientProfile.class) -class UndeployCommandIT { - - @Test - void shouldUndeployProject(QuarkusMainLauncher launcher) { - LaunchResult result = launcher.launch("undeploy"); - assertThat(result.getOutput()).contains( - "StreamX project successfully undeployed from 'default' namespace."); - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/dev/DevCommandTest.java b/core/src/test/java/dev/streamx/cli/command/dev/DevCommandTest.java deleted file mode 100644 index 8fd0e9c4..00000000 --- a/core/src/test/java/dev/streamx/cli/command/dev/DevCommandTest.java +++ /dev/null @@ -1,264 +0,0 @@ -package dev.streamx.cli.command.dev; - -import static dev.streamx.cli.command.util.MeshTestsUtils.cleanUpMesh; -import static org.assertj.core.api.Assertions.assertThat; - -import com.github.dockerjava.api.DockerClient; -import dev.streamx.cli.command.MeshStopper; -import dev.streamx.cli.command.dev.DevCommandTest.DevCommandProfile; -import dev.streamx.cli.command.dev.event.DashboardStarted; -import dev.streamx.cli.command.dev.event.DevReady; -import dev.streamx.runner.event.MeshReloadUpdate; -import dev.streamx.runner.event.MeshStarted; -import io.quarkus.arc.properties.IfBuildProperty; -import io.quarkus.test.junit.QuarkusTestProfile; -import io.quarkus.test.junit.TestProfile; -import io.quarkus.test.junit.main.LaunchResult; -import io.quarkus.test.junit.main.QuarkusMainLauncher; -import io.quarkus.test.junit.main.QuarkusMainTest; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardCopyOption; -import java.util.Arrays; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.stream.Collectors; -import org.awaitility.Awaitility; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; -import org.junit.jupiter.api.io.TempDir; -import org.testcontainers.DockerClientFactory; -import org.testcontainers.shaded.com.github.dockerjava.core.command.ExecStartResultCallback; -import org.testcontainers.shaded.org.apache.commons.io.IOUtils; - - -@QuarkusMainTest -@EnabledIf("dev.streamx.cli.OsUtils#isDockerAvailable") -@TestProfile(DevCommandProfile.class) -class DevCommandTest { - - public static final String MESH_PROPERTY_NAME = "test.mesh.path"; - public static final String HOST_DIRECTORY = "target/test-classes"; - public static final String MESHES_DIRECTORY = HOST_DIRECTORY + "/dev/streamx/cli/command/dev"; - public static final String INITIAL_MESH = MESHES_DIRECTORY + "/initial-mesh.yaml"; - public static final String FAILING_MESH = MESHES_DIRECTORY + "/failing-mesh.yaml"; - public static final String INCREMENTAL_RELOADED_MESH = - MESHES_DIRECTORY + "/incremental-reloaded-mesh.yaml"; - - @TempDir - public Path temp; - - @AfterEach - void awaitDockerResourcesAreRemoved() { - Awaitility.await() - .until(() -> { - try { - Set cleanedUpContainers = - Set.of("pulsar", "pulsar-init", "streamx-dashboard", - "rest-ingestion", "relay", "web-delivery-service"); - cleanUpMesh(cleanedUpContainers); - - return true; - } catch (Exception e) { - return false; - } - }); - } - - @Test - void shouldReactOnMeshChanges(QuarkusMainLauncher launcher) { - // given - var meshPath = temp.resolve("mesh.yaml"); - String meshPathString = meshPath - .toAbsolutePath() - .normalize() - .toString(); - - System.setProperty(MESH_PROPERTY_NAME, meshPathString); - - // when - LaunchResult result = launcher.launch("dev", "-f=" + meshPathString); - - // then - var errorOutput = getErrorOutput(result); - - assertThat(errorOutput).doesNotContain(StateVerifier.MESH_CONTENT_DIFFERENT); - assertThat(errorOutput).doesNotContain(StateVerifier.PROJECT_DIR_DIFFERENT); - assertThat(errorOutput).isBlank(); - - assertThat(result.exitCode()).isZero(); - assertThat(result.getOutput()).contains("StreamX Dashboard started on"); - } - - @NotNull - private static String getErrorOutput(LaunchResult result) { - var errorOutput = result.getErrorOutput(); - if (!errorOutput.isBlank()) { - System.err.println(errorOutput); - } - return errorOutput; - } - - @ApplicationScoped - @IfBuildProperty(name = "streamx.dev.test.profile", stringValue = "true") - public static class StateVerifier { - private static final String PROJECT_DIR_DIFFERENT = - "Provided project directory contend is different than container project."; - private static final String INITIAL_MESH_NOT_EMPTY = - "Initial mesh file must be empty."; - private static final String DASHBOARD_NOT_STARTED = - "Dashboard did not start"; - private static final String MESH_CONTENT_DIFFERENT = - "Provided mesh and container mesh have different content."; - - private final DockerClient client = DockerClientFactory.instance().client(); - - private AtomicBoolean dashboardStarted = new AtomicBoolean(false); - - @Inject - MeshStopper meshStopper; - - @Inject - DashboardRunner dashboardRunner; - - void onMeshStarted(@Observes MeshStarted event) throws Exception { - Path meshPath = getMeshPath(); - - Files.copy(Path.of(FAILING_MESH), meshPath, StandardCopyOption.REPLACE_EXISTING); - } - - void onDevReady(@Observes DevReady event) throws Exception { - if (!dashboardStarted.get()) { - System.err.println(DASHBOARD_NOT_STARTED); - } - - Path meshPath = getMeshPath(); - - if (Files.size(meshPath) > 0) { - System.err.println(INITIAL_MESH_NOT_EMPTY); - } - Files.copy(Path.of(INITIAL_MESH), meshPath, StandardCopyOption.REPLACE_EXISTING); - } - - void onMeshReload(@Observes MeshReloadUpdate event) throws Exception { - Path meshPath = getMeshPath(); - - switch (event.getEvent()) { - case FULL_RELOAD_FINISHED -> { - compareMeshContent(INITIAL_MESH); - compareProjectDirectoryContent(); - - Files.copy(Path.of(FAILING_MESH), meshPath, StandardCopyOption.REPLACE_EXISTING); - } - case INCREMENTAL_RELOAD_FAILED -> { - Files.copy(Path.of(INCREMENTAL_RELOADED_MESH), meshPath, - StandardCopyOption.REPLACE_EXISTING); - } - case INCREMENTAL_RELOAD_FINISHED -> { - Files.deleteIfExists(meshPath); - - dashboardRunner.stopStreamxDashboard(); - meshStopper.scheduleStop(); - } - default -> { - - } - } - } - - private @NotNull Path getMeshPath() { - String meshPath = System.getProperty(MESH_PROPERTY_NAME); - Path meshFile = Path.of(meshPath); - return meshFile; - } - - void onDashboardStarted(@Observes DashboardStarted event) { - dashboardStarted.set(true); - } - - private void compareProjectDirectoryContent() throws InterruptedException { - var command = "ls -1 /data/project"; - - var containerMeshContent = executeCommand(client, command); - - var containerDirectoryContent = extractContainerFiles(containerMeshContent); - var directoryContent = extractHostFiles(); - - if (!containerDirectoryContent.equals(directoryContent)) { - System.err.println(PROJECT_DIR_DIFFERENT); - } - } - - @NotNull - private static Set extractHostFiles() { - return Arrays.stream(new File(HOST_DIRECTORY).listFiles()) - .map(File::getName) - .collect(Collectors.toSet()); - } - - @NotNull - private static Set extractContainerFiles(byte[] containerMeshContent) { - var lines = IOUtils.readLines(new ByteArrayInputStream(containerMeshContent), - StandardCharsets.UTF_8); - - return lines.stream() - .filter(Objects::nonNull) - .map(String::trim) - .collect(Collectors.toSet()); - } - - private void compareMeshContent(String mesh) throws InterruptedException, IOException { - var command = "cat /data/mesh.yaml"; - - var containerMeshContent = executeCommand(client, command); - var meshPath = Paths.get(mesh); - - if (!Arrays.equals(Files.readAllBytes(meshPath), containerMeshContent)) { - System.err.println(MESH_CONTENT_DIFFERENT); - } - } - - private byte[] executeCommand(DockerClient client, String command) throws InterruptedException { - var execId = client - .execCreateCmd("streamx-dashboard") - .withCmd("sh", "-c", command) - .withAttachStdout(true) - .exec() - .getId(); - - var outputStream = new ByteArrayOutputStream(); - var results = new ExecStartResultCallback(outputStream, null); - - client.execStartCmd(execId) - .exec(results) - .awaitCompletion(); - - return outputStream.toByteArray(); - } - } - - public static class DevCommandProfile implements QuarkusTestProfile { - - @Override - public Map getConfigOverrides() { - return Map.of( - "streamx.dev.test.profile", "true", - "streamx.container.startup-timeout-seconds", "15" - ); - } - } - -} diff --git a/core/src/test/java/dev/streamx/cli/command/dev/DockerValidatorTest.java b/core/src/test/java/dev/streamx/cli/command/dev/DockerValidatorTest.java deleted file mode 100644 index 7b3b1d99..00000000 --- a/core/src/test/java/dev/streamx/cli/command/dev/DockerValidatorTest.java +++ /dev/null @@ -1,122 +0,0 @@ -package dev.streamx.cli.command.dev; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchException; - -import com.github.dockerjava.api.DockerClient; -import com.github.dockerjava.api.command.PullImageResultCallback; -import com.github.dockerjava.api.command.RemoveContainerCmd; -import com.github.dockerjava.api.exception.ConflictException; -import dev.streamx.runner.validation.excpetion.DockerContainerNonUniqueException; -import dev.streamx.runner.validation.excpetion.DockerEnvironmentException; -import io.quarkus.arc.impl.Reflections; -import io.quarkus.test.junit.QuarkusTest; -import jakarta.inject.Inject; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.mockito.Mockito; -import org.testcontainers.DockerClientFactory; - - -@QuarkusTest -@EnabledIf("dev.streamx.cli.OsUtils#isDockerAvailable") -class DockerValidatorTest { - - public static final String HELLO_WORLD_IMAGE = "hello-world:latest"; - public static final String HELLO_WORLD_CONTAINER_NAME = "dockerValidatorTestContainer"; - - @Inject - DockerValidator uut; - - @BeforeAll - static void initialize() throws InterruptedException { - DockerClient client = DockerClientFactory.instance().client(); - prepareContainer(client, HELLO_WORLD_CONTAINER_NAME); - } - - @AfterAll - static void destroy() { - DockerClient client = DockerClientFactory.instance().client(); - dropContainer(client, HELLO_WORLD_CONTAINER_NAME).exec(); - } - - @Test - void shouldDetectDuplicatedContainers() { - // given - var usedContainers = Set.of(HELLO_WORLD_CONTAINER_NAME); - - // when - var exception = catchException(() -> uut.validateDockerEnvironment(usedContainers)); - - // then - assertThat(exception) - .isInstanceOf(DockerContainerNonUniqueException.class) - .hasMessage("Containers with names '" + HELLO_WORLD_CONTAINER_NAME + "' already exists."); - } - - @ParameterizedTest - @ValueSource(strings = { - "RunnerValidatorTest", - "streamx", - "Container", - }) - void shouldNotDetectDuplicatedContainers(String testedContainerName) { - // given - var usedContainers = Set.of(testedContainerName); - - // when - var exception = catchException(() -> uut.validateDockerEnvironment(usedContainers)); - - // then - assertThat(exception).isNull(); - } - - private static RemoveContainerCmd dropContainer(DockerClient client, - String containerName) { - return client.removeContainerCmd(containerName); - } - - private static void prepareContainer(DockerClient client, String containerName) - throws InterruptedException { - client.pullImageCmd(HELLO_WORLD_IMAGE) - .exec(new PullImageResultCallback()) - .awaitCompletion(30, TimeUnit.SECONDS); - - try { - client.createContainerCmd(HELLO_WORLD_IMAGE) - .withName(containerName) - .exec(); - } catch (ConflictException e) { - // container already exists - } - } - - @Test - void shouldValidateNoDockerEnvironment() { - DockerClientFactory dockerClientFactory = DockerClientFactory.instance(); - - try { - // given - DockerEnvironmentException dockerEnvironmentException = - new DockerEnvironmentException(new RuntimeException()); - Reflections.writeField(DockerClientFactory.class, "cachedClientFailure", - dockerClientFactory, dockerEnvironmentException); - - // when - Exception exception = catchException(() -> uut.validateDockerEnvironment(Mockito.mock())); - - // then - assertThat(exception) - .isInstanceOf(DockerEnvironmentException.class); - } finally { - Reflections.writeField(DockerClientFactory.class, "cachedClientFailure", - dockerClientFactory, null); - } - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolverInterpolationTest.java b/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolverInterpolationTest.java deleted file mode 100644 index 7c73106e..00000000 --- a/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolverInterpolationTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertThrowsExactly; - -import com.fasterxml.jackson.databind.JsonMappingException; -import io.quarkus.test.junit.QuarkusTest; -import jakarta.inject.Inject; -import java.io.IOException; -import java.nio.file.Path; -import java.util.NoSuchElementException; -import org.junit.jupiter.api.Test; - -@QuarkusTest -class MeshDefinitionResolverInterpolationTest { - - private static final String TEST_MESH_LOCATION = "target/test-classes/mesh-interpolated.yaml"; - private static final Path TEST_MESH_PATH = Path.of(TEST_MESH_LOCATION); - - @Inject - MeshDefinitionResolver uut; - - @Test - void shouldFailWithPropertyUndefined() { - System.clearProperty("config.image.interpolated"); - - JsonMappingException ex = assertThrowsExactly(JsonMappingException.class, - () -> uut.resolve(TEST_MESH_PATH)); - assertThat(ex).hasRootCauseExactlyInstanceOf(NoSuchElementException.class); - } - - @Test - void shouldResolveWithPropertyDefined() throws IOException { - System.setProperty("config.image.interpolated", "value"); - - var result = uut.resolve(TEST_MESH_PATH); - - assertThat(result).isNotNull(); - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolverTest.java b/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolverTest.java deleted file mode 100644 index 3658f025..00000000 --- a/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshDefinitionResolverTest.java +++ /dev/null @@ -1,28 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.quarkus.test.junit.QuarkusTest; -import jakarta.inject.Inject; -import java.io.IOException; -import java.nio.file.Path; -import org.junit.jupiter.api.Test; - -@QuarkusTest -class MeshDefinitionResolverTest { - - private static final String TEST_MESH_LOCATION = "target/test-classes/mesh.yaml"; - private static final Path TEST_MESH_PATH = Path.of(TEST_MESH_LOCATION); - - @Inject - MeshDefinitionResolver uut; - - @Test - void shouldResolveGivenMeshDefinition() throws IOException { - // when - var result = uut.resolve(TEST_MESH_PATH); - - // then - assertThat(result).isNotNull(); - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshResolverTest.java b/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshResolverTest.java deleted file mode 100644 index 9ce354f1..00000000 --- a/core/src/test/java/dev/streamx/cli/command/meshprocessing/MeshResolverTest.java +++ /dev/null @@ -1,131 +0,0 @@ -package dev.streamx.cli.command.meshprocessing; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchException; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.mockito.Mockito.when; - -import dev.streamx.cli.path.CurrentDirectoryProvider; -import dev.streamx.cli.path.FixedCurrentDirectoryProvider; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardCopyOption; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.io.TempDir; -import org.mockito.Mockito; -import picocli.CommandLine.Model.CommandSpec; -import picocli.CommandLine.ParameterException; -import picocli.CommandLine.ParseResult; - -class MeshResolverTest { - - private static final String TEST_MESH_LOCATION = "target/test-classes/mesh.yaml"; - private static final Path TEST_MESH_PATH = Path.of(TEST_MESH_LOCATION); - - private static final String MESH_YAML = "mesh.yaml"; - private static final String MESH_YML = "mesh.yml"; - - MeshResolver uut; - - CurrentDirectoryProvider currentDirectoryProvider; - - @BeforeEach - void setup(@TempDir Path tempDir) { - uut = new MeshResolver(); - currentDirectoryProvider = new FixedCurrentDirectoryProvider(tempDir); - uut.currentDirectoryProvider = this.currentDirectoryProvider; - uut.parseResult = getParseResult(); - } - - @AfterEach - void tearDown() throws IOException { - Files.deleteIfExists(currentDirectoryMeshYaml()); - Files.deleteIfExists(currentDirectoryMeshYml()); - } - - @Test - void shouldResolveCurrentDirectoryMeshYaml() throws IOException { - // given - Files.copy( - TEST_MESH_PATH, currentDirectoryMeshYaml(), - StandardCopyOption.REPLACE_EXISTING); - - // when - var result = uut.resolveMeshPath(null); - - // then - assertNotNull(result); - assertThat(result).isEqualTo(currentDirectoryMeshYaml()); - } - - @Test - void shouldPreferYamlOverYml() throws IOException { - // given - Files.copy( - TEST_MESH_PATH, currentDirectoryMeshYaml(), - StandardCopyOption.REPLACE_EXISTING); - Files.copy( - TEST_MESH_PATH, currentDirectoryMeshYml(), - StandardCopyOption.REPLACE_EXISTING); - - // when - var result = uut.resolveMeshPath(null); - - // then - assertNotNull(result); - assertThat(result).isEqualTo(currentDirectoryMeshYaml()); - } - - @Test - void shouldResolveCurrentDirectoryMeshYml() throws IOException { - // given - Files.copy( - TEST_MESH_PATH, currentDirectoryMeshYml(), - StandardCopyOption.REPLACE_EXISTING); - - // when - var result = uut.resolveMeshPath(null); - - // then - assertNotNull(result); - assertThat(result).isEqualTo(currentDirectoryMeshYml()); - } - - private static ParseResult getParseResult() { - - CommandSpec commandSpec = Mockito.mock(); - when(commandSpec.commandLine()).thenReturn(Mockito.mock()); - - ParseResult parseResult = Mockito.mock(); - when(parseResult.commandSpec()).thenReturn(commandSpec); - when(parseResult.subcommand()).thenReturn(parseResult); - - return parseResult; - } - - @Test - void shouldThrowExceptionIfThereIsNoMeshInCurrentDirectory() { - // when - Exception exception = catchException(() -> uut.resolveMeshPath(null)); - - // then - assertThat(exception).isInstanceOf(ParameterException.class); - assertThat(exception).hasMessageContaining("Missing mesh definition"); - } - - @NotNull - private Path currentDirectoryMeshYaml() { - var currentDir = currentDirectoryProvider.provide(); - return Path.of(currentDir, MESH_YAML); - } - - @NotNull - private Path currentDirectoryMeshYml() { - var currentDir = currentDirectoryProvider.provide(); - return Path.of(currentDir, MESH_YML); - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/run/RunCommandTest.java b/core/src/test/java/dev/streamx/cli/command/run/RunCommandTest.java deleted file mode 100644 index bca3d092..00000000 --- a/core/src/test/java/dev/streamx/cli/command/run/RunCommandTest.java +++ /dev/null @@ -1,78 +0,0 @@ -package dev.streamx.cli.command.run; - -import static dev.streamx.cli.command.util.MeshTestsUtils.cleanUpMesh; -import static org.assertj.core.api.Assertions.assertThat; - -import dev.streamx.cli.command.MeshStopper; -import dev.streamx.cli.command.run.RunCommandTest.RunCommandProfile; -import dev.streamx.runner.event.MeshStarted; -import io.quarkus.arc.properties.IfBuildProperty; -import io.quarkus.test.junit.QuarkusTestProfile; -import io.quarkus.test.junit.TestProfile; -import io.quarkus.test.junit.main.LaunchResult; -import io.quarkus.test.junit.main.QuarkusMainLauncher; -import io.quarkus.test.junit.main.QuarkusMainTest; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.event.Observes; -import jakarta.inject.Inject; -import java.nio.file.Paths; -import java.util.Map; -import java.util.Set; -import org.awaitility.Awaitility; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.condition.EnabledIf; - -@QuarkusMainTest -@EnabledIf("dev.streamx.cli.OsUtils#isDockerAvailable") -@TestProfile(RunCommandProfile.class) -public class RunCommandTest { - - @AfterEach - void awaitDockerResourcesAreRemoved() { - Awaitility.await() - .until(() -> { - try { - Set cleanedUpContainers = - Set.of("pulsar", "pulsar-init", - "rest-ingestion", "relay", "web-delivery-service"); - cleanUpMesh(cleanedUpContainers); - - return true; - } catch (Exception e) { - return false; - } - }); - } - - @Test - void shouldRunStreamxExampleMesh(QuarkusMainLauncher launcher) { - String s = Paths.get("target/test-classes/mesh.yaml") - .toAbsolutePath() - .normalize() - .toString(); - LaunchResult result = launcher.launch("run", "-f=" + s); - - assertThat(result.getOutput()).contains("STREAMX IS READY!"); - } - - @ApplicationScoped - @IfBuildProperty(name = "streamx.run.test.profile", stringValue = "true") - public static class Listener { - - @Inject - MeshStopper meshStopper; - - void onMeshStarted(@Observes MeshStarted event) { - meshStopper.scheduleStop(); - } - } - - public static class RunCommandProfile implements QuarkusTestProfile { - - @Override - public Map getConfigOverrides() { - return Map.of("streamx.run.test.profile", "true"); - } - } -} diff --git a/core/src/test/java/dev/streamx/cli/command/util/MeshTestsUtils.java b/core/src/test/java/dev/streamx/cli/command/util/MeshTestsUtils.java deleted file mode 100644 index 31f844e7..00000000 --- a/core/src/test/java/dev/streamx/cli/command/util/MeshTestsUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -package dev.streamx.cli.command.util; - -import com.github.dockerjava.api.DockerClient; -import dev.streamx.runner.validation.DockerContainerValidator; -import dev.streamx.runner.validation.DockerEnvironmentValidator; -import java.util.Set; - -public class MeshTestsUtils { - public static void cleanUpMesh(Set cleanedUpContainers) { - DockerClient client = new DockerEnvironmentValidator().validateDockerClient(); - for (String container : cleanedUpContainers) { - try { - client.removeContainerCmd(container) - .withForce(true) - .exec(); - } catch (Exception ignored) { - // Ignore - } - } - new DockerContainerValidator().verifyExistingContainers(client, cleanedUpContainers); - } -} diff --git a/core/src/test/java/dev/streamx/cli/interpolation/InterpolatingMapperTest.java b/core/src/test/java/dev/streamx/cli/interpolation/InterpolatingMapperTest.java index ac3156f6..32ccbc55 100644 --- a/core/src/test/java/dev/streamx/cli/interpolation/InterpolatingMapperTest.java +++ b/core/src/test/java/dev/streamx/cli/interpolation/InterpolatingMapperTest.java @@ -8,9 +8,9 @@ import io.quarkus.test.junit.QuarkusTest; import jakarta.inject.Inject; import java.util.Set; +import org.bouncycastle.oer.its.etsi102941.Url; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941.Url; @QuarkusTest public class InterpolatingMapperTest { diff --git a/core/src/test/resources/dev/streamx/cli/command/cloud/deploy/servicemeshes.streamx.dev-v1.yml b/core/src/test/resources/dev/streamx/cli/command/cloud/deploy/servicemeshes.streamx.dev-v1.yml deleted file mode 100644 index c67f3a24..00000000 --- a/core/src/test/resources/dev/streamx/cli/command/cloud/deploy/servicemeshes.streamx.dev-v1.yml +++ /dev/null @@ -1,5155 +0,0 @@ -# Generated by Fabric8 CRDGenerator, manual edits might get overwritten! -apiVersion: "apiextensions.k8s.io/v1" -kind: "CustomResourceDefinition" -metadata: - name: "servicemeshes.streamx.dev" -spec: - group: "streamx.dev" - names: - kind: "ServiceMesh" - plural: "servicemeshes" - shortNames: - - "mesh" - singular: "servicemesh" - scope: "Namespaced" - versions: - - name: "v1alpha1" - schema: - openAPIV3Schema: - properties: - spec: - properties: - defaultImageTag: - type: "string" - defaultRegistry: - type: "string" - delivery: - additionalProperties: - properties: - components: - additionalProperties: - properties: - environment: - additionalProperties: - type: "string" - type: "object" - environmentFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - image: - type: "string" - ports: - items: - type: "string" - type: "array" - repositoryVolume: - type: "string" - volumesFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - type: "object" - type: "object" - environment: - additionalProperties: - type: "string" - type: "object" - environmentFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - image: - type: "string" - incoming: - additionalProperties: - properties: - topic: - type: "string" - type: "object" - type: "object" - port: - type: "integer" - repositoryVolume: - type: "string" - volumesFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - type: "object" - type: "object" - deploymentConfig: - properties: - defaults: - properties: - delivery: - properties: - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - type: "object" - global: - properties: - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - type: "object" - ingestion: - properties: - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - type: "object" - processing: - properties: - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - type: "object" - type: "object" - delivery: - additionalProperties: - properties: - components: - additionalProperties: - properties: - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - sidecar: - type: "boolean" - volumes: - additionalProperties: - properties: - mountPath: - type: "string" - size: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - storageClassName: - type: "string" - type: "object" - type: "object" - type: "object" - type: "object" - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - ingress: - properties: - annotations: - additionalProperties: - type: "string" - type: "object" - enabled: - type: "boolean" - hosts: - items: - properties: - host: - type: "string" - paths: - items: - properties: - path: - type: "string" - pathType: - type: "string" - servicePort: - type: "integer" - type: "object" - type: "array" - type: "object" - type: "array" - ingressClassName: - type: "string" - tls: - items: - properties: - hosts: - items: - type: "string" - type: "array" - secretName: - type: "string" - type: "object" - type: "array" - waitForLoadBalancer: - type: "boolean" - type: "object" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - volumes: - additionalProperties: - properties: - mountPath: - type: "string" - size: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - storageClassName: - type: "string" - type: "object" - type: "object" - type: "object" - type: "object" - ingestion: - additionalProperties: - properties: - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - ingress: - properties: - annotations: - additionalProperties: - type: "string" - type: "object" - enabled: - type: "boolean" - hosts: - items: - properties: - host: - type: "string" - paths: - items: - properties: - path: - type: "string" - pathType: - type: "string" - servicePort: - type: "integer" - type: "object" - type: "array" - type: "object" - type: "array" - ingressClassName: - type: "string" - tls: - items: - properties: - hosts: - items: - type: "string" - type: "array" - secretName: - type: "string" - type: "object" - type: "array" - waitForLoadBalancer: - type: "boolean" - type: "object" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - volumes: - additionalProperties: - properties: - mountPath: - type: "string" - size: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - storageClassName: - type: "string" - type: "object" - type: "object" - type: "object" - type: "object" - processing: - additionalProperties: - properties: - imagePullPolicy: - type: "string" - imagePullSecrets: - items: - properties: - name: - type: "string" - type: "object" - type: "array" - podDisruptionBudget: - properties: - enabled: - type: "boolean" - maxUnavailable: - type: "integer" - minAvailable: - type: "integer" - type: "object" - probes: - properties: - liveness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - readiness: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - startup: - properties: - exec: - properties: - command: - items: - type: "string" - type: "array" - type: "object" - failureThreshold: - type: "integer" - grpc: - properties: - port: - type: "integer" - service: - type: "string" - type: "object" - httpGet: - properties: - host: - type: "string" - httpHeaders: - items: - properties: - name: - type: "string" - value: - type: "string" - type: "object" - type: "array" - path: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - scheme: - type: "string" - type: "object" - initialDelaySeconds: - type: "integer" - periodSeconds: - type: "integer" - successThreshold: - type: "integer" - tcpSocket: - properties: - host: - type: "string" - port: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - terminationGracePeriodSeconds: - type: "integer" - timeoutSeconds: - type: "integer" - type: "object" - type: "object" - replicas: - type: "integer" - resources: - properties: - claims: - items: - properties: - name: - type: "string" - request: - type: "string" - type: "object" - type: "array" - limits: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - requests: - additionalProperties: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: "object" - scheduling: - properties: - affinity: - properties: - nodeAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - preference: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - properties: - nodeSelectorTerms: - items: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchFields: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - type: "object" - type: "array" - type: "object" - type: "object" - podAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - podAntiAffinity: - properties: - preferredDuringSchedulingIgnoredDuringExecution: - items: - properties: - podAffinityTerm: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - weight: - type: "integer" - type: "object" - type: "array" - requiredDuringSchedulingIgnoredDuringExecution: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - mismatchLabelKeys: - items: - type: "string" - type: "array" - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - namespaces: - items: - type: "string" - type: "array" - topologyKey: - type: "string" - type: "object" - type: "array" - type: "object" - type: "object" - priorityClassName: - type: "string" - tolerations: - items: - properties: - effect: - type: "string" - key: - type: "string" - operator: - type: "string" - tolerationSeconds: - type: "integer" - value: - type: "string" - type: "object" - type: "array" - topologySpreadConstraints: - items: - properties: - labelSelector: - properties: - matchExpressions: - items: - properties: - key: - type: "string" - operator: - type: "string" - values: - items: - type: "string" - type: "array" - type: "object" - type: "array" - matchLabels: - additionalProperties: - type: "string" - type: "object" - type: "object" - matchLabelKeys: - items: - type: "string" - type: "array" - maxSkew: - type: "integer" - minDomains: - type: "integer" - nodeAffinityPolicy: - type: "string" - nodeTaintsPolicy: - type: "string" - topologyKey: - type: "string" - whenUnsatisfiable: - type: "string" - type: "object" - type: "array" - type: "object" - stateful: - type: "boolean" - storageClassName: - type: "string" - strategy: - properties: - rollingUpdate: - properties: - maxSurge: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - maxUnavailable: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - type: "object" - type: - type: "string" - type: "object" - volumes: - additionalProperties: - properties: - mountPath: - type: "string" - size: - anyOf: - - type: "integer" - - type: "string" - x-kubernetes-int-or-string: true - storageClassName: - type: "string" - type: "object" - type: "object" - type: "object" - type: "object" - type: "object" - environment: - additionalProperties: - type: "string" - type: "object" - environmentFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - ingestion: - additionalProperties: - properties: - environment: - additionalProperties: - type: "string" - type: "object" - environmentFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - image: - type: "string" - volumesFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - type: "object" - type: "object" - processing: - additionalProperties: - properties: - environment: - additionalProperties: - type: "string" - type: "object" - environmentFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - image: - type: "string" - incoming: - additionalProperties: - properties: - topic: - type: "string" - type: "object" - type: "object" - outgoing: - additionalProperties: - properties: - topic: - type: "string" - type: "object" - type: "object" - volumesFrom: - properties: - configs: - items: - type: "string" - type: "array" - secrets: - items: - type: "string" - type: "array" - type: "object" - type: "object" - type: "object" - sources: - additionalProperties: - properties: - outgoing: - items: - type: "string" - type: "array" - type: "object" - type: "object" - type: "object" - status: - properties: - conditions: - items: - properties: - lastTransitionTime: - type: "string" - message: - type: "string" - observedGeneration: - type: "integer" - status: - type: "string" - type: - type: "string" - type: "object" - type: "array" - observedGeneration: - type: "integer" - type: "object" - type: "object" - served: true - storage: true - subresources: - status: {} diff --git a/core/src/test/resources/dev/streamx/cli/command/dev/failing-mesh.yaml b/core/src/test/resources/dev/streamx/cli/command/dev/failing-mesh.yaml deleted file mode 100644 index 06d2c4cc..00000000 --- a/core/src/test/resources/dev/streamx/cli/command/dev/failing-mesh.yaml +++ /dev/null @@ -1,32 +0,0 @@ -defaultRegistry: ghcr.io/streamx-dev/streamx -defaultImageTag: latest-jvm - -sources: - cli: - outgoing: - - "pages" - -ingestion: - rest-ingestion: - environment: - QUARKUS_HTTP_AUTH_PERMISSION_BEARER_POLICY: "per" - -processing: - relay: - image: sample-relay-processing-service - incoming: - incoming-pages: - topic: inboxes/pages - outgoing: - outgoing-pages: - topic: outboxes/pages - -delivery: - web-delivery-service: - image: sample-web-delivery-service - incoming: - pages: - topic: outboxes/pages - port: 8081 - environment: - STREAMX_DELIVERY-SERVICE_READINESS-CHECK_CHANNELS-QUIET-TIME: "3000" diff --git a/core/src/test/resources/dev/streamx/cli/command/dev/incremental-reloaded-mesh.yaml b/core/src/test/resources/dev/streamx/cli/command/dev/incremental-reloaded-mesh.yaml deleted file mode 100644 index 0b18a59c..00000000 --- a/core/src/test/resources/dev/streamx/cli/command/dev/incremental-reloaded-mesh.yaml +++ /dev/null @@ -1,32 +0,0 @@ -defaultRegistry: ghcr.io/streamx-dev/streamx -defaultImageTag: latest-jvm - -sources: - cli: - outgoing: - - "pages" - -ingestion: - rest-ingestion: - environment: - QUARKUS_HTTP_AUTH_PERMISSION_BEARER_POLICY: "permit" - -processing: - relay: - image: sample-relay-processing-service - incoming: - incoming-pages: - topic: inboxes/pages - outgoing: - outgoing-pages: - topic: outboxes/page - -delivery: - web-delivery-service: - image: sample-web-delivery-service - incoming: - pages: - topic: outboxes/page - port: 8081 - environment: - STREAMX_DELIVERY-SERVICE_READINESS-CHECK_CHANNELS-QUIET-TIME: "3000" diff --git a/core/src/test/resources/dev/streamx/cli/command/dev/initial-mesh.yaml b/core/src/test/resources/dev/streamx/cli/command/dev/initial-mesh.yaml deleted file mode 100644 index da297fa3..00000000 --- a/core/src/test/resources/dev/streamx/cli/command/dev/initial-mesh.yaml +++ /dev/null @@ -1,32 +0,0 @@ -defaultRegistry: ghcr.io/streamx-dev/streamx -defaultImageTag: latest-jvm - -sources: - cli: - outgoing: - - "pages" - -ingestion: - rest-ingestion: - environment: - QUARKUS_HTTP_AUTH_PERMISSION_BEARER_POLICY: "permit" - -processing: - relay: - image: sample-relay-processing-service - incoming: - incoming-pages: - topic: inboxes/pages - outgoing: - outgoing-pages: - topic: outboxes/pages - -delivery: - web-delivery-service: - image: sample-web-delivery-service - incoming: - pages: - topic: outboxes/pages - port: 8081 - environment: - STREAMX_DELIVERY-SERVICE_READINESS-CHECK_CHANNELS-QUIET-TIME: "3000" diff --git a/e2e-tests/pom.xml b/e2e-tests/pom.xml index dac74e2e..747eb9a0 100644 --- a/e2e-tests/pom.xml +++ b/e2e-tests/pom.xml @@ -43,12 +43,6 @@ quarkus-junit5 test - - dev.streamx - streamx-runner - test - - diff --git a/e2e-tests/src/test/java/dev/streamx/cli/OsUtils.java b/e2e-tests/src/test/java/dev/streamx/cli/OsUtils.java deleted file mode 100644 index f6b7a575..00000000 --- a/e2e-tests/src/test/java/dev/streamx/cli/OsUtils.java +++ /dev/null @@ -1,14 +0,0 @@ -package dev.streamx.cli; - -import dev.streamx.runner.validation.DockerEnvironmentValidator; - -public class OsUtils { - public static boolean isDockerAvailable() { - try { - new DockerEnvironmentValidator().validateDockerClient(); - return true; - } catch (Exception e) { - return false; - } - } -} diff --git a/entrypoint/src/main/java/dev/streamx/cli/EntrypointMain.java b/entrypoint/src/main/java/dev/streamx/cli/EntrypointMain.java index 81edfde6..ecc0885b 100644 --- a/entrypoint/src/main/java/dev/streamx/cli/EntrypointMain.java +++ b/entrypoint/src/main/java/dev/streamx/cli/EntrypointMain.java @@ -7,7 +7,7 @@ public class EntrypointMain { private static final SimpleDateFormat DATE_FORMAT = - new SimpleDateFormat("yyyy_MM_dd__HH_mm_ss_SSS"); + new SimpleDateFormat("yyyy_MM_dd__HH_mm_ss_SSS"); private static final String LOG_FILE_PATH_PROPERTY_NAME = "%prod.quarkus.log.file.path"; private static final String STREAMX_LOG_FILE_NAME_PATTERN = "%s/.streamx/logs/streamx-%s.log"; diff --git a/entrypoint/src/test/java/dev/streamx/cli/EntrypointMainTest.java b/entrypoint/src/test/java/dev/streamx/cli/EntrypointMainTest.java index a790c2e5..482ae4e1 100644 --- a/entrypoint/src/test/java/dev/streamx/cli/EntrypointMainTest.java +++ b/entrypoint/src/test/java/dev/streamx/cli/EntrypointMainTest.java @@ -31,32 +31,6 @@ void shouldLaunchStreamxCommand() { Assertions.assertTrue(StreamxCommand.isLaunched()); } - @ParameterizedTest - @ValueSource(strings = { - "1.8.0_211", - "9.0.1", - "11.0.4", - "12", - "12.0.1" - }) - void shouldFailTooLowJavaVersions(String javaVersion) { - // given - System.clearProperty("java.version"); - System.setProperty("java.version", javaVersion); - - ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); - System.setOut(new PrintStream(byteArrayOutputStream)); - - // when - EntrypointMain.main(new String[] {}); - - // then - Assertions.assertFalse(StreamxCommand.isLaunched()); - Assertions.assertTrue( - byteArrayOutputStream.toString().contains("Java 17 or higher is required!") - ); - } - @Test void shouldOverrideProdFileLogName() throws IOException { // given diff --git a/pom.xml b/pom.xml index e0ec4b0a..e76df6fd 100644 --- a/pom.xml +++ b/pom.xml @@ -75,11 +75,6 @@ ${project.version} - - dev.streamx - streamx-runner - ${streamx.version} - dev.streamx ingestion-client