Skip to content

Commit

Permalink
Merge pull request #387 from wttech/fix-error-handling
Browse files Browse the repository at this point in the history
fixed error handling
  • Loading branch information
dprzybyl committed Jan 3, 2023
2 parents aef5d4a + 30eca4c commit 797d315
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.cognifide.apm.api.actions.ActionResult;
import com.cognifide.apm.api.actions.Context;
import com.cognifide.apm.api.status.Status;
import com.cognifide.apm.main.actions.forauthorizable.ForAuthorizable;
import com.cognifide.apm.main.utils.MessagingUtils;
import javax.jcr.RepositoryException;
import org.apache.jackrabbit.api.security.user.Authorizable;
Expand All @@ -42,12 +43,12 @@ public class CreateAuthorizable implements Action {

private final String externalId;

private final Boolean ignoreIfExists;
private final boolean ignoreIfExists;

private final CreateAuthorizableStrategy createStrategy;

public CreateAuthorizable(String id, String password, String path, String externalId,
Boolean ignoreIfExists, CreateAuthorizableStrategy createStrategy) {
boolean ignoreIfExists, CreateAuthorizableStrategy createStrategy) {
this.id = id;
this.password = password;
this.path = path;
Expand All @@ -70,16 +71,19 @@ public ActionResult process(Context context, boolean simulate) {
ActionResult actionResult = context.createActionResult();
try {
Authorizable authorizable = context.getAuthorizableManager().getAuthorizableIfExists(id);
LOGGER.info("Creating authorizable with id = " + id);
LOGGER.info("Creating authorizable with id = {}", id);
if (authorizable != null) {
logMessage(actionResult, authorizable);
} else {
authorizable = createStrategy.create(id, password, path, externalId, context, actionResult, simulate);
createStrategy.create(id, password, path, externalId, context, actionResult, simulate);
}
context.setCurrentAuthorizable(authorizable);
} catch (RepositoryException e) {
actionResult.logError(MessagingUtils.createMessage(e));
}
if (actionResult.getStatus() != Status.ERROR) {
ActionResult forAuthorizableActionResult = new ForAuthorizable(id, false, createStrategy == CreateAuthorizableStrategy.GROUP).process(context);
actionResult.changeStatus(forAuthorizableActionResult.getStatus(), forAuthorizableActionResult.getMessages().get(0).getText());
}
return actionResult;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import com.cognifide.apm.core.grammar.utils.RequiredVariablesChecker
import com.cognifide.apm.core.logger.Position
import com.cognifide.apm.core.logger.Progress
import org.antlr.v4.runtime.ParserRuleContext
import org.antlr.v4.runtime.tree.RuleNode
import org.apache.sling.api.resource.ResourceResolver

class ScriptRunner(
Expand Down Expand Up @@ -63,42 +64,62 @@ class ScriptRunner(
return progress
}

private inner class Executor(private val executionContext: ExecutionContext) :
com.cognifide.apm.core.grammar.antlr.ApmLangBaseVisitor<Unit>() {
private inner class Executor(
private val executionContext: ExecutionContext,
private var globalResult: Status = Status.SUCCESS
) : com.cognifide.apm.core.grammar.antlr.ApmLangBaseVisitor<Status>() {

override fun visitDefineVariable(ctx: DefineVariableContext) {
private fun shouldVisitNextChild(): Boolean {
return globalResult != Status.ERROR
}

override fun shouldVisitNextChild(node: RuleNode, currentResult: Status?): Boolean {
return shouldVisitNextChild()
}

override fun aggregateResult(aggregate: Status?, nextResult: Status?): Status {
globalResult = if (nextResult == Status.ERROR) Status.ERROR else globalResult
return globalResult
}

override fun visitDefineVariable(ctx: DefineVariableContext): Status {
val variableName = ctx.IDENTIFIER().toString()
val variableValue = executionContext.resolveArgument(ctx.argument())
executionContext.setVariable(variableName, variableValue)
progress(ctx, Status.SUCCESS, "define", "Defined variable: $variableName= $variableValue")
return Status.SUCCESS
}

override fun visitRequireVariable(ctx: RequireVariableContext) {
override fun visitRequireVariable(ctx: RequireVariableContext): Status {
val variableName = ctx.IDENTIFIER().toString()
if (executionContext.getVariable(variableName) == null) {
val status = if (validateOnly) Status.WARNING else Status.ERROR
progress(ctx, status, "require", "Variable \"$variableName\" is required")
}
return Status.SUCCESS
}

override fun visitForEach(ctx: ForEachContext) {
override fun visitForEach(ctx: ForEachContext): Status {
val values: List<Map<String, ApmType>> = readValues(ctx)
for ((index, value) in values.withIndex()) {
try {
executionContext.createLocalContext()
val valueStr = value.map { it.key + "=" + it.value }
.joinToString()
progress(ctx, Status.SUCCESS, "for-each", "$index. Begin: $valueStr")
value.forEach { (k, v) -> executionContext.setVariable(k, v) }
visit(ctx.body())
progress(ctx, Status.SUCCESS, "for-each", "$index. End")
} finally {
executionContext.removeLocalContext()
if (shouldVisitNextChild()) {
try {
executionContext.createLocalContext()
val valueStr = value.map { it.key + "=" + it.value }
.joinToString()
progress(ctx, Status.SUCCESS, "for-each", "$index. Begin: $valueStr")
value.forEach { (k, v) -> executionContext.setVariable(k, v) }
visit(ctx.body())
progress(ctx, Status.SUCCESS, "for-each", "$index. End")
} finally {
executionContext.removeLocalContext()
}
}
}
return Status.SUCCESS
}

override fun visitRunScript(ctx: RunScriptContext) {
override fun visitRunScript(ctx: RunScriptContext): Status {
val path = ctx.path().STRING_LITERAL().toPlainString()
val arguments = executionContext.resolveArguments(ctx.namedArguments())
val loadScript = executionContext.loadScript(path)
Expand All @@ -118,15 +139,16 @@ class ScriptRunner(
} else {
progress(ctx, Status.ERROR, "run", result.toMessages(), arguments)
}
return Status.SUCCESS
}

override fun visitGenericCommand(ctx: GenericCommandContext) {
val commandName = getIdentifier(ctx.commandName().identifier()).toUpperCase()
override fun visitGenericCommand(ctx: GenericCommandContext): Status {
val commandName = getIdentifier(ctx.commandName().identifier()).uppercase()
val arguments = executionContext.resolveArguments(ctx.complexArguments())
visitGenericCommand(ctx, commandName, arguments, ctx.body())
return visitGenericCommand(ctx, commandName, arguments, ctx.body())
}

override fun visitAllowDenyCommand(ctx: AllowDenyCommandContext) {
override fun visitAllowDenyCommand(ctx: AllowDenyCommandContext): Status {
val commandName = if (ctx.ALLOW() != null) "ALLOW" else "DENY"
val argument = executionContext.resolveArgument(ctx.argument())
val arguments = executionContext.resolveArguments(ctx.complexArguments())
Expand All @@ -136,13 +158,13 @@ class ScriptRunner(
arguments.required + argument
}
val newArguments = Arguments(required, arguments.named, arguments.flags)
visitGenericCommand(ctx, commandName, newArguments)
return visitGenericCommand(ctx, commandName, newArguments)
}

private fun visitGenericCommand(
ctx: ParserRuleContext, commandName: String, arguments: Arguments, body: BodyContext? = null
) {
if (validateOnly) {
): Status {
return if (validateOnly) {
visitGenericCommandValidateMode(ctx, commandName, arguments, body)
} else {
visitGenericCommandRunMode(ctx, commandName, arguments, body)
Expand All @@ -151,27 +173,29 @@ class ScriptRunner(

private fun visitGenericCommandRunMode(
ctx: ParserRuleContext, commandName: String, arguments: Arguments, body: BodyContext?
) {
): Status {
try {
if (body != null) {
executionContext.createLocalContext()
}
val status = actionInvoker.runAction(executionContext, commandName, arguments)
if (status != Status.ERROR && body != null) {
if (status == Status.SUCCESS && body != null) {
visit(body)
}
return status
} catch (e: ArgumentResolverException) {
progress(ctx, Status.ERROR, commandName, "Action failed: ${e.message}")
} finally {
if (body != null) {
executionContext.removeLocalContext()
}
}
return Status.ERROR
}

private fun visitGenericCommandValidateMode(
ctx: ParserRuleContext, commandName: String, arguments: Arguments, body: BodyContext?
) {
): Status {
try {
if (body != null) {
executionContext.createLocalContext()
Expand All @@ -189,12 +213,14 @@ class ScriptRunner(
executionContext.removeLocalContext()
}
}
return Status.SUCCESS
}

override fun visitImportScript(ctx: ImportScriptContext) {
override fun visitImportScript(ctx: ImportScriptContext): Status {
val result = ImportScript(executionContext).import(ctx)
executionContext.variableHolder.setAll(result.variableHolder)
progress(ctx, Status.SUCCESS, "import", result.toMessages())
return Status.SUCCESS
}

private fun readValues(ctx: ForEachContext): List<Map<String, ApmType>> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@
import com.cognifide.apm.core.services.ResourceResolverProvider;
import com.cognifide.apm.core.services.version.ScriptVersion;
import com.cognifide.apm.core.services.version.VersionService;
import com.cognifide.apm.core.utils.RuntimeUtils;
import com.cognifide.apm.core.utils.sling.SlingHelper;
import java.lang.management.ManagementFactory;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.ResourceResolver;
import org.osgi.service.component.annotations.Activate;
Expand All @@ -55,6 +58,8 @@
@Designate(ocd = ApmInstallService.Configuration.class, factory = true)
public class ApmInstallService extends AbstractLauncher {

private static final String AEM_MUTABLE_CONTENT_INSTANCE = "aem-install-mutable-content";

@Reference
private ResourceResolverProvider resolverProvider;

Expand All @@ -72,7 +77,13 @@ public class ApmInstallService extends AbstractLauncher {

@Activate
public void activate(Configuration config) {
SlingHelper.operateTraced(resolverProvider, resolver -> processScripts(config, resolver));
SlingHelper.operateTraced(resolverProvider, resolver -> {
boolean compositeNodeStore = RuntimeUtils.determineCompositeNodeStore(resolver);
String instanceName = ManagementFactory.getRuntimeMXBean().getName();
if (!compositeNodeStore || StringUtils.contains(instanceName, AEM_MUTABLE_CONTENT_INSTANCE)) {
processScripts(config, resolver);
}
});
}

private void processScripts(Configuration config, ResourceResolver resolver) throws PersistenceException {
Expand Down

0 comments on commit 797d315

Please sign in to comment.