Skip to content

Commit

Permalink
[WIP] verify
Browse files Browse the repository at this point in the history
  • Loading branch information
gansheer committed Jan 31, 2025
1 parent ef8e269 commit e0d4385
Show file tree
Hide file tree
Showing 11 changed files with 572 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,15 @@ public class CamelPluginAction extends AbstractCamelJBangAction {
private final AddCamelPluginAction addPluginAction;
private final ExportKubernetesCamelPluginAction exportKubernetesPluginAction;
private final DeleteKubernetesCamelPluginAction deleteKubernetesPluginAction;
private final VerifyKubernetesIntegrationCamelPluginAction verifyKubernetesIntegrationPluginAction;


public CamelPluginAction(CamelPluginAction.Builder builder) {
super("plugin", builder);
this.addPluginAction = builder.addPluginAction;
this.exportKubernetesPluginAction = builder.exportKubernetesPluginAction;
this.deleteKubernetesPluginAction = builder.deleteKubernetesPluginAction;
this.verifyKubernetesIntegrationPluginAction = builder.verifyKubernetesIntegrationPluginAction;
}

@Override
Expand All @@ -41,6 +43,8 @@ public void doExecute(TestContext context) {
exportKubernetesPluginAction.doExecute(context);
} else if (this.deleteKubernetesPluginAction != null) {
deleteKubernetesPluginAction.doExecute(context);
} else if (this.verifyKubernetesIntegrationPluginAction != null) {
verifyKubernetesIntegrationPluginAction.doExecute(context);
}
}

Expand All @@ -56,13 +60,18 @@ public DeleteKubernetesCamelPluginAction getDeleteKubernetesPluginAction() {
return deleteKubernetesPluginAction;
}

public VerifyKubernetesIntegrationCamelPluginAction getVerifyKubernetesIntegrationPluginAction() {
return verifyKubernetesIntegrationPluginAction;
}

/**
* Action builder.
*/
public static final class Builder extends AbstractCamelJBangAction.Builder<CamelPluginAction, CamelPluginAction.Builder> {
private AddCamelPluginAction addPluginAction;
private ExportKubernetesCamelPluginAction exportKubernetesPluginAction;
private DeleteKubernetesCamelPluginAction deleteKubernetesPluginAction;
private VerifyKubernetesIntegrationCamelPluginAction verifyKubernetesIntegrationPluginAction;

/**
* Set add plugin action.
Expand Down Expand Up @@ -94,6 +103,16 @@ public Builder deleteKubernetesPluginAction(DeleteKubernetesCamelPluginAction de
return this;
}

/**
* Set verify kubernetes integration plugin action.
* @param verifyKubernetesIntegrationPluginAction
* @return
*/
public Builder verifyKubernetesIntegrationPluginAction(VerifyKubernetesIntegrationCamelPluginAction verifyKubernetesIntegrationPluginAction) {
this.verifyKubernetesIntegrationPluginAction = verifyKubernetesIntegrationPluginAction;
return this;
}

@Override
public CamelPluginAction build() {
return new CamelPluginAction(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ public DeleteKubernetesCamelPluginAction(Builder builder) {
public void doExecute(TestContext context) {
logger.info("Deleting integration deployed from a Camel Kubernetes project ...");
List<String> fullArgs = new ArrayList<>();
fullArgs.add("kubernetes");
fullArgs.add("delete");
if (integrationResource != null) {
fullArgs.add(integrationResource.getFile().toPath().toAbsolutePath().toString());
Expand All @@ -78,7 +77,7 @@ public void doExecute(TestContext context) {
fullArgs.add("--namespace");
fullArgs.add(namespace);
}
camelJBang().camelApp().run("plugin", fullArgs.toArray(String[]::new));
camelJBang().camelApp().run("kubernetes", fullArgs.toArray(String[]::new));

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import org.citrusframework.context.TestContext;
import org.citrusframework.exceptions.CitrusRuntimeException;
import org.citrusframework.jbang.ProcessAndOutput;
import org.citrusframework.spi.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -79,8 +80,7 @@ public void doExecute(TestContext context) {
}

List<String> fullArgs = new ArrayList<>();
fullArgs.add("kubernetes");
fullArgs.add("export");
fullArgs.add("run");
fullArgs.add(integrationFile.toAbsolutePath().toString());
if (imageBuilder != null){
fullArgs.add("--image-builder");
Expand All @@ -93,7 +93,7 @@ public void doExecute(TestContext context) {

if (buildProperties != null){
for (String property : buildProperties) {
fullArgs.add("--build-properties");
fullArgs.add("--build-property");
fullArgs.add(property);
}
}
Expand All @@ -105,13 +105,25 @@ public void doExecute(TestContext context) {
}
}

if (args != null){
if (args != null) {
fullArgs.addAll(args);
}

camelJBang().camelApp().run("plugin", fullArgs.toArray(String[]::new));
// TODO manage this better and maybe use --wait
ProcessAndOutput pao = camelJBang().camelApp().run("kubernetes", fullArgs.toArray(String[]::new));
while (pao.getProcess().isAlive()) {
continue;
}

// TODO add a printLog ?
logger.info(pao.getOutput());
if (pao.getProcess().exitValue() != 0) {
throw new CitrusRuntimeException(String.format("Failed to start Camel integration in kubernetes - exit code %s", pao.getProcess().exitValue()));
}

}


public Resource getIntegrationResource() {
return integrationResource;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,245 @@
package org.citrusframework.camel.actions;

import org.citrusframework.camel.CamelSettings;
import org.citrusframework.context.TestContext;
import org.citrusframework.exceptions.ActionTimeoutException;
import org.citrusframework.exceptions.CitrusRuntimeException;
import org.citrusframework.jbang.ProcessAndOutput;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* Verifies Camel integration in kubernetes via Camel JBang. Waits for a log message to be present.
* Raises errors when the Camel integration log message is not available.
* Check operation is automatically retried for a given amount of attempts.
*/
public class VerifyKubernetesIntegrationCamelPluginAction extends AbstractCamelJBangAction {

private static final Logger INTEGRATION_LOG = LoggerFactory.getLogger("INTEGRATION_LOGS");

/**
* Logger
*/
private static final Logger logger = LoggerFactory.getLogger(VerifyKubernetesIntegrationCamelPluginAction.class);

/** The integration name */
private final String integrationName;
/** Label name and value used as a pod selector */
private final String label;
/** Kubernetes Namespace */
private final String namespace;

private final String logMessage;
private final int maxAttempts;
private final long delayBetweenAttempts;

private final boolean printLogs;

/** Camel Jbang command arguments */
private final List<String> args;

protected VerifyKubernetesIntegrationCamelPluginAction(VerifyKubernetesIntegrationCamelPluginAction.Builder builder) {
super("verify-kubernetes-integration", builder);
this.integrationName = builder.integrationName;
this.label = builder.label;
this.namespace = builder.namespace;
this.logMessage = builder.logMessage;
this.maxAttempts = builder.maxAttempts;
this.delayBetweenAttempts = builder.delayBetweenAttempts;
this.printLogs = builder.printLogs;
this.args = builder.args;
}


@Override
public void doExecute(TestContext context) {
logger.info("Verify Camel integration in Kubernetes ...");
List<String> fullArgs = new ArrayList<>();
fullArgs.add("logs");

if (integrationName != null) {
fullArgs.add("--name");
fullArgs.add(integrationName);
}
if (label != null){
fullArgs.add("--label");
fullArgs.add(label);
}
if (namespace != null) {
fullArgs.add("--namespace");
fullArgs.add(namespace);
}

if (args != null) {
fullArgs.addAll(args);
}

verifyIntegrationLog(logMessage, fullArgs);
}

private void verifyIntegrationLog(String message, List<String> fullArgs) {
if (printLogs) {
INTEGRATION_LOG.info(String.format("Waiting for Camel integration in kubernetes to log message"));
}

String log;
int offset = 0;

ProcessAndOutput pao = camelJBang().camelApp().runAsync("kubernetes", fullArgs.toArray(String[]::new));
for (int i = 0; i < maxAttempts; i++) {

log = pao.getOutput();
if (printLogs && (offset < log.length())) {
INTEGRATION_LOG.info(log.substring(offset));
offset = log.length();
}

if (log.contains(message)) {
logger.info("Verified Camel integration in kubernetes logs - All values OK!");
return;
}

if (!printLogs) {
logger.warn(String.format("Waiting for Camel integration in kubernetes to log message - retry in %s ms", delayBetweenAttempts));
}

try {
Thread.sleep(delayBetweenAttempts);
} catch (InterruptedException e) {
logger.warn("Interrupted while waiting for Camel integration in kubernetes logs", e);
}
}

throw new ActionTimeoutException((maxAttempts * delayBetweenAttempts),
new CitrusRuntimeException(String.format("Failed to verify Camel integration in kubernetes - " +
"has not printed message '%s' after %d attempts", message, maxAttempts)));
}

public String getIntegrationName() {
return integrationName;
}

public String getLogMessage() {
return logMessage;
}

/**
* Action builder.
*/
public static final class Builder extends AbstractCamelJBangAction.Builder<VerifyKubernetesIntegrationCamelPluginAction, VerifyKubernetesIntegrationCamelPluginAction.Builder> {

private String integrationName;
private String label;
private String namespace;

private String logMessage;

private int maxAttempts = CamelSettings.getMaxAttempts();
private long delayBetweenAttempts = CamelSettings.getDelayBetweenAttempts();

private boolean printLogs = CamelSettings.isPrintLogs();

private final List<String> args = new ArrayList<>();

/**
* Identify Camel JBang process for this route.
* @param name
* @return
*/
public Builder integration(String name) {
this.integrationName = name;
return this;
}

/**
* Sets the integration name.
* @param name
* @return
*/
public Builder integrationName(String name) {
this.integrationName = name;
return this;
}

/**
* Sets the integration label.
* @param label
* @return
*/
public Builder label(String label) {
this.label = label;
return this;
}

/**
* Sets the namespace.
* @param namespace
* @return
*/
public Builder namespace(String namespace) {
this.namespace = namespace;
return this;
}

public Builder printLogs(boolean printLogs) {
this.printLogs = printLogs;
return this;
}

public Builder waitForLogMessage(String logMessage) {
this.logMessage = logMessage;
return this;
}

public Builder maxAttempts(int maxAttempts) {
this.maxAttempts = maxAttempts;
return this;
}

public Builder delayBetweenAttempts(long delayBetweenAttempts) {
this.delayBetweenAttempts = delayBetweenAttempts;
return this;
}


/**
* Adds a command argument.
* @param arg
* @return
*/
public Builder withArg(String arg) {
this.args.add(arg);
return this;
}

/**
* Adds a command argument with name and value.
* @param name
* @param value
* @return
*/
public Builder withArg(String name, String value) {
this.args.add(name);
this.args.add(value);
return this;
}

/**
* Adds command arguments.
* @param args
* @return
*/
public Builder withArgs(String... args) {
this.args.addAll(Arrays.asList(args));
return this;
}
@Override
public VerifyKubernetesIntegrationCamelPluginAction build() {
return new VerifyKubernetesIntegrationCamelPluginAction(this);
}
}
}
Loading

0 comments on commit e0d4385

Please sign in to comment.