This is an automated email from the ASF dual-hosted git repository. marat pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel-karavan.git
commit 96aaec7e2dd8b32dc8e0894e1542a37f0e3143c0 Author: Marat Gubaidullin <ma...@talismancloud.io> AuthorDate: Fri Sep 1 12:12:46 2023 -0400 Infinispan chaos for #817 --- .../camel/karavan/docker/DockerEventListener.java | 10 +- .../camel/karavan/docker/DockerForGitea.java | 101 +++++++++++++++++++-- .../camel/karavan/docker/DockerForInfinispan.java | 28 +++--- .../apache/camel/karavan/docker/DockerService.java | 5 +- .../karavan/docker/model/DockerComposeService.java | 15 ++- .../karavan/docker/model/HealthCheckConfig.java | 11 +++ .../apache/camel/karavan/service/DelayRoute.java | 10 +- .../apache/camel/karavan/service/EventService.java | 33 +------ .../camel/karavan/service/KaravanService.java | 62 ++++++++----- .../camel/karavan/service/ScheduledService.java | 12 +-- .../org/apache/camel/karavan/shared/EventType.java | 5 +- .../karavan-app/src/main/resources/gitea/app.ini | 94 ------------------- .../src/main/resources/services/internal.yaml | 6 +- karavan-web/karavan-infinispan/pom.xml | 4 + .../karavan/infinispan/InfinispanService.java | 84 +++++++++-------- .../src/main/resources/application.properties | 1 - .../camel/karavan/infinispan/DataGridTest.java | 2 +- 17 files changed, 242 insertions(+), 241 deletions(-) diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java index 0bf1b6ce..e13a6c76 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerEventListener.java @@ -59,9 +59,9 @@ public class DockerEventListener implements ResultCallback<Event> { public void onContainerEvent(Event event, Container container) { String status = event.getStatus(); - if (status.startsWith("health_status:") && container.getNames()[0].equals("/gitea")) { - onGiteaHealthEvent(container, event); - } +// if (status.startsWith("health_status:") && container.getNames()[0].equals("/gitea")) { +// onGiteaHealthEvent(container, event); +// } if (infinispanService.isReady()) { if (status.startsWith("health_status:")) { if (container.getNames()[0].equals("/infinispan")) { @@ -108,14 +108,14 @@ public class DockerEventListener implements ResultCallback<Event> { String status = event.getStatus(); String health = status.replace("health_status: ", ""); LOGGER.infof("Container %s health status: %s", container.getNames()[0], health); - eventBus.publish(GITEA_CONTAINER_STARTED, health); +// eventBus.publish(GITEA_CONTAINER_STARTED, health); } public void onInfinispanHealthEvent(Container container, Event event) { String status = event.getStatus(); String health = status.replace("health_status: ", ""); LOGGER.infof("Container %s health status: %s", container.getNames()[0], health); - eventBus.publish(INFINISPAN_STARTED, health); +// eventBus.publish(INFINISPAN_STARTED, health); } public void onDevModeHealthEvent(Container container, Event event) { diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForGitea.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForGitea.java index 8cde9667..6c3fb784 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForGitea.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForGitea.java @@ -17,7 +17,11 @@ package org.apache.camel.karavan.docker; import com.github.dockerjava.api.command.ExecCreateCmdResponse; +import com.github.dockerjava.api.command.HealthState; import com.github.dockerjava.api.model.Container; +import io.quarkus.vertx.ConsumeEvent; +import io.vertx.core.eventbus.EventBus; +import io.vertx.core.json.Json; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; import org.apache.camel.karavan.infinispan.model.ContainerStatus; @@ -26,9 +30,18 @@ import org.apache.camel.karavan.service.GitService; import org.apache.camel.karavan.service.GiteaService; import org.jboss.logging.Logger; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.HashMap; +import java.util.Map; + @ApplicationScoped public class DockerForGitea { + public static final String GITEA_CREATE_INSTANCE_DELAY = "GITEA_CREATE_INSTANCE_DELAY"; + public static final String GITEA_CREATE_INSTANCE = "GITEA_CREATE_INSTANCE"; + private static final Logger LOGGER = Logger.getLogger(DockerForGitea.class.getName()); protected static final String GITEA_CONTAINER_NAME = "gitea"; @@ -42,28 +55,25 @@ public class DockerForGitea { @Inject GitService gitService; + @Inject + EventBus eventBus; + public void startGitea() { try { LOGGER.info("Gitea container is starting..."); var compose = dockerService.getInternalDockerComposeService(GITEA_CONTAINER_NAME); Container c = dockerService.createContainerFromCompose(compose, ContainerStatus.ContainerType.internal); - copyAppIni(c.getId()); dockerService.runContainer(GITEA_CONTAINER_NAME); + eventBus.publish(GITEA_CREATE_INSTANCE, null); LOGGER.info("Gitea container is started"); } catch (Exception e) { LOGGER.error(e.getMessage()); } } - protected void copyAppIni(String containerId) { - try { - LOGGER.info("Copying Gitea app.ini"); - String ini = DockerServiceUtils.getResourceFile("/gitea/app.ini"); - dockerService.copyFile(containerId, "/etc/gitea","app.ini", ini); - LOGGER.info("Copied Gitea app.ini"); - } catch (Exception e) { - LOGGER.error(e.getMessage()); - } + @ConsumeEvent(value = GITEA_CREATE_INSTANCE, blocking = true, ordered = true) + void installGiteaInGiteaContainer(String giteaHealth) { + installGitea(); } protected void createGiteaUser() { @@ -86,6 +96,7 @@ public class DockerForGitea { } } + protected void checkGiteaInstance() { try { Container gitea = dockerService.getContainerByName(GITEA_CONTAINER_NAME); @@ -98,7 +109,77 @@ public class DockerForGitea { } } + protected void createGiteaInstance() { + try { + LOGGER.info("Creating Gitea Instance"); + Container gitea = dockerService.getContainerByName(GITEA_CONTAINER_NAME); +// ExecCreateCmdResponse instance = dockerService.execCreate(gitea.getId(), +// "curl", "-X", "POST", "localhost:3000", "-d", +// "db_type=sqlite3&db_host=localhost%3A3306&db_user=root&db_passwd=&db_name=gitea" + +// "&ssl_mode=disable&db_schema=&db_path=%2Fvar%2Flib%2Fgitea%2Fdata%2Fgitea.db&app_name=Gitea%3A+Git+with+a+cup+of+tea" + +// "&repo_root_path=%2Fvar%2Flib%2Fgitea%2Fgit%2Frepositories&lfs_root_path=%2Fvar%2Flib%2Fgitea%2Fgit%2Flfs&run_user=git" + +// "&domain=localhost&ssh_port=2222&http_port=3000&app_url=http%3A%2F%2Flocalhost%3A3000%2F&log_root_path=%2Fvar%2Flib%2Fgitea%2Fdata%2Flog" + +// "&smtp_addr=&smtp_port=&smtp_from=&smtp_user=&smtp_passwd=&enable_federated_avatar=on&enable_open_id_sign_in=on" + +// "&enable_open_id_sign_up=on&default_allow_create_organization=on&default_enable_timetracking=on" + +// "&no_reply_address=noreply.localhost&password_algorithm=pbkdf2&admin_name=&admin_email=&admin_passwd=&admin_confirm_passwd=", +// "-H", "'Content-Type: application/x-www-form-urlencoded'"); + ExecCreateCmdResponse instance = dockerService.getDockerClient().execCreateCmd(gitea.getId()) + .withAttachStdout(true).withAttachStderr(true) + .withCmd("curl", "-X", "POST", "localhost:3000", "-d", + "db_type=sqlite3&db_host=localhost%3A3306&db_user=root&db_passwd=&db_name=gitea" + + "&ssl_mode=disable&db_schema=&db_path=%2Fvar%2Flib%2Fgitea%2Fdata%2Fgitea.db&app_name=Gitea%3A+Git+with+a+cup+of+tea" + + "&repo_root_path=%2Fvar%2Flib%2Fgitea%2Fgit%2Frepositories&lfs_root_path=%2Fvar%2Flib%2Fgitea%2Fgit%2Flfs&run_user=git" + + "&domain=localhost&ssh_port=2222&http_port=3000&app_url=http%3A%2F%2Flocalhost%3A3000%2F&log_root_path=%2Fvar%2Flib%2Fgitea%2Fdata%2Flog" + + "&smtp_addr=&smtp_port=&smtp_from=&smtp_user=&smtp_passwd=&enable_federated_avatar=on&enable_open_id_sign_in=on" + + "&enable_open_id_sign_up=on&default_allow_create_organization=on&default_enable_timetracking=on" + + "&no_reply_address=noreply.localhost&password_algorithm=pbkdf2&admin_name=&admin_email=&admin_passwd=&admin_confirm_passwd=", + "-H", "'Content-Type: application/x-www-form-urlencoded'") + .exec(); + + dockerService.getDockerClient().execStartCmd(instance.getId()).start().awaitCompletion(); + LOGGER.info(instance.toString()); + dockerService.execStart(instance.getId()); + LOGGER.info("Created Gitea Instance"); + } catch (Exception e) { + LOGGER.error(e.getMessage()); + } + } + public void installGitea() { + createGiteaInstance(); checkGiteaInstance(); } + + private String getURL() throws UnsupportedEncodingException { + Map<String, String> map = new HashMap(); + map.put("db_type", "sqlite3"); + map.put("db_host", "localhost:3306"); + map.put("db_user", "root"); + map.put("db_passwd", ""); + map.put("db_name", "gitea"); + map.put("ssl_mode", "disable"); + map.put("db_schema", ""); + map.put("db_path", "/data/gitea.db"); + map.put("app_name", "karavan"); + map.put("repo_root_path", "/data/repositories"); + map.put("lfs_root_path", ""); + map.put("run_user", "git"); + map.put("domain", "localhost"); + map.put("ssh_port", "2222"); + map.put("http_port", "3000"); + map.put("app_url", "http://localhost:3000/"); + map.put("log_root_path", "/data/log"); + map.put("enable_federated_avatar", "on"); + map.put("enable_open_id_sign_in", "on"); + map.put("enable_open_id_sign_up", "on"); + map.put("default_allow_create_organization", "on"); + map.put("default_enable_timetracking", "on"); + map.put("no_reply_address", "noreply.localhost"); + map.put("password_algorithm", "pbkdf2"); + map.put("admin_name", "karavan"); + map.put("admin_email", "karavan@karavan.space"); + map.put("admin_passwd", "karavan"); + map.put("admin_confirm_passwd", "karavan"); + return URLEncoder.encode(Json.encode(map), StandardCharsets.UTF_8.toString()); + } } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForInfinispan.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForInfinispan.java index b6b6673e..b7c8c197 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForInfinispan.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerForInfinispan.java @@ -16,7 +16,6 @@ */ package org.apache.camel.karavan.docker; -import com.github.dockerjava.api.command.HealthState; import io.vertx.core.eventbus.EventBus; import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; @@ -24,8 +23,8 @@ import org.apache.camel.karavan.infinispan.model.ContainerStatus; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.jboss.logging.Logger; +import java.util.Arrays; import java.util.List; -import static org.apache.camel.karavan.shared.EventType.INFINISPAN_STARTED; @ApplicationScoped public class DockerForInfinispan { @@ -49,23 +48,24 @@ public class DockerForInfinispan { try { LOGGER.info("Infinispan is starting..."); var compose = dockerService.getInternalDockerComposeService(INFINISPAN_CONTAINER_NAME); - compose.getEnvironmentList().addAll(List.of("USER=" + infinispanUsername, "PASS=" + infinispanPassword)); + compose.addEnvironment("USER", infinispanUsername); + compose.addEnvironment("PASS", infinispanPassword); dockerService.createContainerFromCompose(compose, ContainerStatus.ContainerType.internal); dockerService.runContainer(INFINISPAN_CONTAINER_NAME); LOGGER.info("Infinispan is started"); } catch (Exception e) { - LOGGER.error(e.getMessage()); + LOGGER.error(e.getCause().getMessage()); } } - public void checkInfinispanHealth() { - dockerService.listContainers(false).stream() - .filter(c -> c.getState().equals("running")) - .forEach(c -> { - HealthState hs = dockerService.inspectContainer(c.getId()).getState().getHealth(); - if (c.getNames()[0].equals("/" + INFINISPAN_CONTAINER_NAME)) { - eventBus.publish(INFINISPAN_STARTED, hs.getStatus()); - } - }); - } +// public void checkInfinispanHealth() { +// dockerService.listContainers(false).stream() +// .filter(c -> c.getState().equals("running")) +// .forEach(c -> { +// HealthState hs = dockerService.inspectContainer(c.getId()).getState().getHealth(); +// if (c.getNames()[0].equals("/" + INFINISPAN_CONTAINER_NAME)) { +// eventBus.publish(INFINISPAN_STARTED, hs.getStatus()); +// } +// }); +// } } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java index 10c8018e..e8b22d2c 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/DockerService.java @@ -145,7 +145,7 @@ public class DockerService extends DockerServiceUtils { public Container createContainerFromCompose(DockerComposeService compose, ContainerStatus.ContainerType type) throws InterruptedException { List<Container> containers = getDockerClient().listContainersCmd().withShowAll(true).withNameFilter(List.of(compose.getContainer_name())).exec(); if (containers.isEmpty()) { - LOGGER.infof("Compose Service starting for ", compose.getContainer_name()); + LOGGER.infof("Compose Service starting for %s", compose.getContainer_name()); HealthCheck healthCheck = getHealthCheck(compose.getHealthcheck()); List<String> env = compose.getEnvironment() != null ? compose.getEnvironmentList() : List.of(); @@ -248,7 +248,6 @@ public class DockerService extends DockerServiceUtils { return getDockerClient().inspectContainerCmd(id).exec(); } - public ExecCreateCmdResponse execCreate(String id, String... cmd) { return getDockerClient().execCreateCmd(id) .withAttachStdout(true).withAttachStderr(true) @@ -354,7 +353,7 @@ public class DockerService extends DockerServiceUtils { .build(); } - private DockerClient getDockerClient() { + public DockerClient getDockerClient() { if (dockerClient == null) { dockerClient = DockerClientImpl.getInstance(getDockerClientConfig(), getDockerHttpClient()); } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/DockerComposeService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/DockerComposeService.java index eed5fa37..a348c706 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/DockerComposeService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/DockerComposeService.java @@ -1,5 +1,7 @@ package org.apache.camel.karavan.docker.model; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -67,12 +69,19 @@ public class DockerComposeService { } public Map<String, String> getEnvironment() { - return environment; + return environment != null ? environment : new HashMap<>(); } public List<String> getEnvironmentList() { - return environment.entrySet().stream() - .map(e -> e.getKey().concat("=").concat(e.getValue())).collect(Collectors.toList()); + return environment != null + ? environment.entrySet().stream() .map(e -> e.getKey().concat("=").concat(e.getValue())).collect(Collectors.toList()) + : new ArrayList<>(); + } + + public void addEnvironment(String key, String value) { + Map<String, String> map = getEnvironment(); + map.put(key, value); + setEnvironment(map); } public void setEnvironment(Map<String, String> environment) { diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/HealthCheckConfig.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/HealthCheckConfig.java index 46f766df..4a631414 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/HealthCheckConfig.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/docker/model/HealthCheckConfig.java @@ -52,4 +52,15 @@ public class HealthCheckConfig { public void setStart_period(String start_period) { this.start_period = start_period; } + + @Override + public String toString() { + return "HealthCheckConfig{" + + "interval='" + interval + '\'' + + ", retries=" + retries + + ", timeout='" + timeout + '\'' + + ", start_period='" + start_period + '\'' + + ", test=" + test + + '}'; + } } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/DelayRoute.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/DelayRoute.java index ba6f4794..8e594246 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/DelayRoute.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/DelayRoute.java @@ -1,16 +1,20 @@ package org.apache.camel.karavan.service; import org.apache.camel.builder.endpoint.EndpointRouteBuilder; +import org.apache.camel.karavan.infinispan.InfinispanService; -import static org.apache.camel.karavan.shared.EventType.DELAY_MESSAGE; -import static org.apache.camel.karavan.shared.EventType.DEVMODE_CONTAINER_READY; +import static org.apache.camel.karavan.shared.EventType.*; public class DelayRoute extends EndpointRouteBuilder { @Override public void configure() throws Exception { - from(vertx(DELAY_MESSAGE)) + from(vertx(DEVMODE_DELAY_MESSAGE)) .delay(500) .to(vertx(DEVMODE_CONTAINER_READY)); + +// from(vertx(InfinispanService.INFINISPAN_START_DELAY)) +// .delay(1000) +// .toD(vertx(InfinispanService.INFINISPAN_START)); } } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java index e4a8bc1a..4fa56052 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/EventService.java @@ -16,6 +16,7 @@ import org.apache.camel.karavan.shared.ConfigService; import org.apache.camel.karavan.shared.Constants; import org.apache.camel.karavan.shared.EventType; import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.infinispan.client.hotrod.exceptions.TransportException; import org.jboss.logging.Logger; import jakarta.enterprise.context.ApplicationScoped; @@ -62,36 +63,6 @@ public class EventService { @Inject EventBus eventBus; - @ConsumeEvent(value = START_INFINISPAN_IN_DOCKER, blocking = true, ordered = true) - void startInfinispan1(String data) { - dockerForInfinispan.startInfinispan(); - dockerForInfinispan.checkInfinispanHealth(); - } - - @ConsumeEvent(value = INFINISPAN_STARTED, blocking = true, ordered = true) - void startServices1(String infinispanHealth) { - if (infinispanHealth.equals(Constants.HEALTHY_STATUS)) { - infinispanService.start(false); - infinispanService.clearAllStatuses(); - if (!ConfigService.inKubernetes()) { - dockerForKaravan.startKaravanHeadlessContainer(); - dockerService.collectContainersStatuses(); - } - eventBus.publish(EventType.IMPORT_PROJECTS, ""); - eventBus.publish(EventType.START_INFRASTRUCTURE_LISTENERS, ""); - } - } - - @ConsumeEvent(value = GITEA_STARTED, blocking = true, ordered = true) - void startInfinispanAfterGitea(String giteaHealth) { - eventBus.publish(EventType.START_INFINISPAN_IN_DOCKER, null); - } - - @ConsumeEvent(value = GITEA_CONTAINER_STARTED, blocking = true, ordered = true) - void installGiteaInGiteaContainer(String giteaHealth) { - dockerForGitea.installGitea(); - } - void startServices(String infinispanHealth) { eventBus.publish(EventType.IMPORT_PROJECTS, ""); eventBus.publish(EventType.START_INFRASTRUCTURE_LISTENERS, ""); @@ -137,7 +108,7 @@ public class EventService { LABEL_PROJECT_ID, projectId, RELOAD_TRY_COUNT, ++reloadCount ); - eventBus.publish(DELAY_MESSAGE, JsonObject.mapFrom(message)); + eventBus.publish(DEVMODE_DELAY_MESSAGE, JsonObject.mapFrom(message)); } } diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java index 1af18359..1eac2bbd 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/KaravanService.java @@ -19,22 +19,26 @@ package org.apache.camel.karavan.service; import io.quarkus.runtime.Quarkus; import io.quarkus.runtime.ShutdownEvent; import io.quarkus.runtime.StartupEvent; +import io.quarkus.vertx.ConsumeEvent; import io.vertx.core.eventbus.EventBus; +import jakarta.inject.Singleton; import org.apache.camel.karavan.docker.DockerForGitea; +import org.apache.camel.karavan.docker.DockerForInfinispan; import org.apache.camel.karavan.docker.DockerService; +import org.apache.camel.karavan.infinispan.InfinispanService; import org.apache.camel.karavan.kubernetes.KubernetesService; import org.apache.camel.karavan.shared.ConfigService; -import org.apache.camel.karavan.shared.Constants; -import org.apache.camel.karavan.shared.EventType; import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.faulttolerance.Retry; import org.jboss.logging.Logger; -import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; import java.io.IOException; -@ApplicationScoped +import static org.apache.camel.karavan.shared.EventType.IMPORT_PROJECTS; + +@Singleton public class KaravanService { private static final Logger LOGGER = Logger.getLogger(KaravanService.class.getName()); @@ -52,34 +56,44 @@ public class KaravanService { DockerForGitea dockerForGitea; @Inject - GitService gitService; + DockerForInfinispan dockerForInfinispan; + + @Inject + InfinispanService infinispanService; @Inject EventBus eventBus; - void onStart(@Observes StartupEvent ev) { - LOGGER.info("Starting Karavan"); + private static final String START_INTERNAL_DOCKER_SERVICES = "START_INTERNAL_DOCKER_SERVICES"; + private static final String START_SERVICES = "START_SERVICES"; + + void onStart(@Observes StartupEvent ev) throws Exception { if (!ConfigService.inKubernetes()) { - if (ConfigService.isHeadless()) { - LOGGER.info("Starting Karavan Headless in Docker"); - } else { - LOGGER.info("Starting Karavan with Docker"); - if (!dockerService.checkDocker()){ - Quarkus.asyncExit(); - } else { - dockerService.createNetwork(); - dockerService.startListeners(); - if (giteaInstall) { - dockerForGitea.startGitea(); - } else { - eventBus.publish(EventType.START_INFINISPAN_IN_DOCKER, null); - } - } - } + eventBus.publish(START_INTERNAL_DOCKER_SERVICES, null); } else { LOGGER.info("Starting Karavan in " + (kubernetesService.isOpenshift() ? "OpenShift" : "Kubernetes")); - eventBus.publish(EventType.INFINISPAN_STARTED, Constants.HEALTHY_STATUS); } + eventBus.publish(START_SERVICES, null); + } + + @ConsumeEvent(value = START_INTERNAL_DOCKER_SERVICES, blocking = true) + void startInternalDockerServices(String data) { + LOGGER.info("Starting Karavan in Docker"); + if (!dockerService.checkDocker()){ + Quarkus.asyncExit(); + } else { + dockerService.createNetwork(); + dockerService.startListeners(); + dockerForInfinispan.startInfinispan(); + if (giteaInstall) { + dockerForGitea.startGitea(); + } + } + } + + @ConsumeEvent(value = START_SERVICES, blocking = true) + void startServices(String data) throws Exception { + infinispanService.tryStart(false); } void onStop(@Observes ShutdownEvent ev) throws IOException { diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ScheduledService.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ScheduledService.java index 392d6790..d4dad13a 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ScheduledService.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/service/ScheduledService.java @@ -80,12 +80,12 @@ public class ScheduledService { } } - @Scheduled(every = "{karavan.container.infinispan.interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) - void checkInfinispanHealth() { - if (!infinispanService.isReady()) { - dockerForInfinispan.checkInfinispanHealth(); - } - } +// @Scheduled(every = "{karavan.container.infinispan.interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) +// void checkInfinispanHealth() { +// if (!infinispanService.isReady()) { +// dockerForInfinispan.checkInfinispanHealth(); +// } +// } @Scheduled(every = "{karavan.camel.status.interval}", concurrentExecution = Scheduled.ConcurrentExecution.SKIP) void collectCamelStatuses() { diff --git a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java index 89664a03..be501549 100644 --- a/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java +++ b/karavan-web/karavan-app/src/main/java/org/apache/camel/karavan/shared/EventType.java @@ -25,12 +25,9 @@ public class EventType { public static final String IMPORT_PROJECTS = "IMPORT_PROJECTS"; public static final String START_INFINISPAN_IN_DOCKER = "START_INFINISPAN_IN_DOCKER"; - public static final String INFINISPAN_STARTED = "INFINISPAN_STARTED"; - public static final String GITEA_CONTAINER_STARTED = "GITEA_CONTAINER_STARTED"; - public static final String GITEA_STARTED = "GITEA_STARTED"; public static final String CONTAINER_STATUS = "CONTAINER_STATUS"; public static final String DEVMODE_CONTAINER_READY = "DEVMODE_STATUS"; - public static final String DELAY_MESSAGE = "DELAY_MESSAGE"; + public static final String DEVMODE_DELAY_MESSAGE = "DEVMODE_DELAY_MESSAGE"; } diff --git a/karavan-web/karavan-app/src/main/resources/gitea/app.ini b/karavan-web/karavan-app/src/main/resources/gitea/app.ini deleted file mode 100644 index fb1fcf37..00000000 --- a/karavan-web/karavan-app/src/main/resources/gitea/app.ini +++ /dev/null @@ -1,94 +0,0 @@ -APP_NAME = Karavan -RUN_USER = git -RUN_MODE = prod -WORK_PATH = /var/lib/gitea - -[repository] -ROOT =/var/lib/gitea/data/repositories - -[repository.local] -LOCAL_COPY_PATH = /tmp/gitea/local-repo - -[repository.upload] -TEMP_PATH = /tmp/gitea/uploads - -[server] -APP_DATA_PATH = /var/lib/gitea -SSH_DOMAIN = 0.0.0.0 -HTTP_PORT = 3000 -ROOT_URL = http://0.0.0.0:3000/ -DISABLE_SSH = false -; In rootless gitea container only internal ssh server is supported -START_SSH_SERVER = true -SSH_PORT = 2222 -SSH_LISTEN_PORT = 2222 -BUILTIN_SSH_SERVER_USER = git -LFS_START_SERVER = false -DOMAIN = 0.0.0.0 -OFFLINE_MODE = false - -[database] -PATH =/var/lib/gitea/data/gitea.db -DB_TYPE = sqlite3 -HOST = localhost:3306 -NAME = gitea -USER = root -PASSWD = -SCHEMA = -SSL_MODE = disable -LOG_SQL = false - -[session] -PROVIDER_CONFIG = /var/lib/gitea/data/sessions -PROVIDER = file - -[picture] -AVATAR_UPLOAD_PATH = /var/lib/gitea/data/avatars -REPOSITORY_AVATAR_UPLOAD_PATH = /var/lib/gitea/data/repo-avatars - -[attachment] -PATH = /var/lib/gitea/data/attachments - -[log] -ROOT_PATH =/var/lib/gitea/data/log -MODE = console -LEVEL = info - -[security] -INSTALL_LOCK = true -SECRET_KEY = -REVERSE_PROXY_LIMIT = 1 -REVERSE_PROXY_TRUSTED_PROXIES = * -PASSWORD_HASH_ALGO = pbkdf2 - -[service] -DISABLE_REGISTRATION = true -REQUIRE_SIGNIN_VIEW = true -REGISTER_EMAIL_CONFIRM = false -ENABLE_NOTIFY_MAIL = false -ALLOW_ONLY_EXTERNAL_REGISTRATION = false -ENABLE_CAPTCHA = false -DEFAULT_KEEP_EMAIL_PRIVATE = false -DEFAULT_ALLOW_CREATE_ORGANIZATION = false -DEFAULT_ENABLE_TIMETRACKING = false -NO_REPLY_ADDRESS = noreply.localhost -ENABLE_BASIC_AUTHENTICATION = true - -[lfs] -PATH = /var/lib/gitea/git/lfs - -[mailer] -ENABLED = false - -[openid] -ENABLE_OPENID_SIGNIN = false -ENABLE_OPENID_SIGNUP = false - -[cron.update_checker] -ENABLED = false - -[repository.pull-request] -DEFAULT_MERGE_STYLE = merge - -[repository.signing] -DEFAULT_TRUST_MODEL = committer diff --git a/karavan-web/karavan-app/src/main/resources/services/internal.yaml b/karavan-web/karavan-app/src/main/resources/services/internal.yaml index 5c970982..413e2061 100644 --- a/karavan-web/karavan-app/src/main/resources/services/internal.yaml +++ b/karavan-web/karavan-app/src/main/resources/services/internal.yaml @@ -17,10 +17,6 @@ services: gitea: image: gitea/gitea:1.20.2-rootless restart: always - environment: - GITEA__server__APP_DATA_PATH: /data -# - USER_UID=1000 -# - USER_GID=1000 ports: - "3000:3000" healthcheck: @@ -28,4 +24,4 @@ services: interval: 30s timeout: 10s retries: 10 - start_period: 10s + start_period: 2s diff --git a/karavan-web/karavan-infinispan/pom.xml b/karavan-web/karavan-infinispan/pom.xml index 66c1bb66..72701f9c 100644 --- a/karavan-web/karavan-infinispan/pom.xml +++ b/karavan-web/karavan-infinispan/pom.xml @@ -39,6 +39,10 @@ <groupId>io.quarkus</groupId> <artifactId>quarkus-infinispan-client</artifactId> </dependency> + <dependency> + <groupId>io.quarkus</groupId> + <artifactId>quarkus-smallrye-fault-tolerance</artifactId> + </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-junit5</artifactId> diff --git a/karavan-web/karavan-infinispan/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java b/karavan-web/karavan-infinispan/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java index 36301239..97e93d05 100644 --- a/karavan-web/karavan-infinispan/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java +++ b/karavan-web/karavan-infinispan/src/main/java/org/apache/camel/karavan/infinispan/InfinispanService.java @@ -16,15 +16,17 @@ */ package org.apache.camel.karavan.infinispan; +import io.quarkus.runtime.StartupEvent; import io.quarkus.vertx.ConsumeEvent; import io.smallrye.mutiny.tuples.Tuple2; import io.vertx.core.eventbus.EventBus; import io.vertx.core.json.JsonObject; -import jakarta.enterprise.context.ApplicationScoped; -import jakarta.enterprise.inject.Default; +import jakarta.enterprise.event.Observes; import jakarta.inject.Inject; +import jakarta.inject.Singleton; import org.apache.camel.karavan.infinispan.model.*; import org.eclipse.microprofile.config.inject.ConfigProperty; +import org.eclipse.microprofile.faulttolerance.Retry; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheManager; import org.infinispan.client.hotrod.Search; @@ -35,7 +37,6 @@ import org.infinispan.commons.marshall.ProtoStreamMarshaller; import org.infinispan.query.dsl.QueryFactory; import org.jboss.logging.Logger; - import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; @@ -47,15 +48,14 @@ import java.util.stream.Collectors; import static org.infinispan.query.remote.client.ProtobufMetadataManagerConstants.PROTOBUF_METADATA_CACHE_NAME; -@Default -@ApplicationScoped +@Singleton public class InfinispanService { - @ConfigProperty(name ="karavan.infinispan.hosts") + @ConfigProperty(name = "karavan.infinispan.hosts") String infinispanHosts; - @ConfigProperty(name ="karavan.infinispan.username") + @ConfigProperty(name = "karavan.infinispan.username") String infinispanUsername; - @ConfigProperty(name ="karavan.infinispan.password") + @ConfigProperty(name = "karavan.infinispan.password") String infinispanPassword; @Inject @@ -82,7 +82,12 @@ public class InfinispanService { public static final String CODE_RELOAD_COMMAND = "CODE_RELOAD_COMMAND"; protected static final String CODE_RELOAD_COMMAND_INTERNAL = "CODE_RELOAD_COMMAND_INTERNAL"; - public void start(boolean startCodeReloadListener) { + @Retry(maxRetries = 100, delay = 2000) + public void tryStart(boolean startCodeReloadListener) throws Exception { + start(startCodeReloadListener); + } + + void start(boolean startCodeReloadListener) throws Exception { LOGGER.info("InfinispanService is starting in remote mode"); ProtoStreamMarshaller marshaller = new ProtoStreamMarshaller(); @@ -99,29 +104,34 @@ public class InfinispanService { cacheManager = new RemoteCacheManager(builder.build()); - projects = getOrCreateCache(Project.CACHE, false); - files = getOrCreateCache(ProjectFile.CACHE, false); - containerStatuses = getOrCreateCache(ContainerStatus.CACHE, false); - pipelineStatuses = getOrCreateCache(PipelineStatus.CACHE, false); - deploymentStatuses = getOrCreateCache(DeploymentStatus.CACHE, false); - serviceStatuses = getOrCreateCache(ServiceStatus.CACHE, false); - camelStatuses = getOrCreateCache(CamelStatus.CACHE, false); - commits = getOrCreateCache("commits", false); - transits = getOrCreateCache("transits", false); - deploymentStatuses = getOrCreateCache(DeploymentStatus.CACHE, false); - codeReloadCommands = getOrCreateCache("code_reload_commands", true); - - cacheManager.getCache(PROTOBUF_METADATA_CACHE_NAME).put("karavan.proto", getResourceFile("/proto/karavan.proto")); - - if (startCodeReloadListener) { - cacheManager.getCache("code_reload_commands").addClientListener(new CodeReloadListener(eventBus)); + if (cacheManager.getConnectionCount() > 0 ) { + + projects = getOrCreateCache(Project.CACHE, false); + files = getOrCreateCache(ProjectFile.CACHE, false); + containerStatuses = getOrCreateCache(ContainerStatus.CACHE, false); + pipelineStatuses = getOrCreateCache(PipelineStatus.CACHE, false); + deploymentStatuses = getOrCreateCache(DeploymentStatus.CACHE, false); + serviceStatuses = getOrCreateCache(ServiceStatus.CACHE, false); + camelStatuses = getOrCreateCache(CamelStatus.CACHE, false); + commits = getOrCreateCache("commits", false); + transits = getOrCreateCache("transits", false); + deploymentStatuses = getOrCreateCache(DeploymentStatus.CACHE, false); + codeReloadCommands = getOrCreateCache("code_reload_commands", true); + + cacheManager.getCache(PROTOBUF_METADATA_CACHE_NAME).put("karavan.proto", getResourceFile("/proto/karavan.proto")); + + if (startCodeReloadListener) { + cacheManager.getCache("code_reload_commands").addClientListener(new CodeReloadListener(eventBus)); + } + + ready.set(true); + LOGGER.info("InfinispanService is started in remote mode"); + } else { + throw new Exception("Not connected..."); } - - ready.set(true); - LOGGER.info("InfinispanService is started in remote mode"); } - private <K, V> RemoteCache<K, V> getOrCreateCache(String name, boolean command) { + private <K, V> RemoteCache<K, V> getOrCreateCache(String name, boolean command) { String config = getResourceFile(command ? "/cache/command-cache-config.xml" : "/cache/data-cache-config.xml"); return cacheManager.administration().getOrCreateCache(name, new StringConfiguration(String.format(config, name))); } @@ -193,15 +203,15 @@ public class InfinispanService { } public void deleteProject(String projectId) { - projects.remove(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT,projectId)); + projects.remove(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT, projectId)); } public void deleteProjectFile(String projectId, String filename) { - files.remove(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT,filename)); + files.remove(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT, filename)); } public Project getProject(String projectId) { - return projects.get(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT,projectId)); + return projects.get(GroupedKey.create(projectId, DEFAULT_ENVIRONMENT, projectId)); } public PipelineStatus getPipelineStatus(String projectId, String environment) { @@ -267,7 +277,7 @@ public class InfinispanService { } public void setTransit(String projectId, String env, String containerName) { - transits.put(GroupedKey.create(projectId,env,containerName), true); + transits.put(GroupedKey.create(projectId, env, containerName), true); } public List<ContainerStatus> getContainerStatuses() { @@ -397,10 +407,10 @@ public class InfinispanService { public void clearAllStatuses() { CompletableFuture.allOf( - deploymentStatuses.clearAsync(), - containerStatuses.clearAsync(), - pipelineStatuses.clearAsync(), - camelStatuses.clearAsync() + deploymentStatuses.clearAsync(), + containerStatuses.clearAsync(), + pipelineStatuses.clearAsync(), + camelStatuses.clearAsync() ).join(); } diff --git a/karavan-web/karavan-infinispan/src/main/resources/application.properties b/karavan-web/karavan-infinispan/src/main/resources/application.properties index b708de8f..cfc20af0 100644 --- a/karavan-web/karavan-infinispan/src/main/resources/application.properties +++ b/karavan-web/karavan-infinispan/src/main/resources/application.properties @@ -11,4 +11,3 @@ quarkus.infinispan-client.health.enabled=false # Infinispan client intelligence # Use BASIC as a Docker for Mac workaround quarkus.infinispan-client.client-intelligence=BASIC - diff --git a/karavan-web/karavan-infinispan/src/test/java/org/apache/camel/karavan/infinispan/DataGridTest.java b/karavan-web/karavan-infinispan/src/test/java/org/apache/camel/karavan/infinispan/DataGridTest.java index 11f1085c..aac22b8c 100644 --- a/karavan-web/karavan-infinispan/src/test/java/org/apache/camel/karavan/infinispan/DataGridTest.java +++ b/karavan-web/karavan-infinispan/src/test/java/org/apache/camel/karavan/infinispan/DataGridTest.java @@ -25,7 +25,7 @@ public class DataGridTest { InfinispanService infinispanService; @BeforeAll - public void setup() { + public void setup() throws Exception { infinispanService.start(true); }