Search in sources :

Example 11 with ProcessDefinition

use of com.walmartlabs.concord.runtime.v2.model.ProcessDefinition in project concord by walmartlabs.

the class EventRecordingExecutionListener method afterCommand.

@Override
public Result afterCommand(Runtime runtime, VM vm, State state, ThreadId threadId, Command cmd) {
    if (!eventConfiguration.recordEvents()) {
        return Result.CONTINUE;
    }
    if (!(cmd instanceof StepCommand)) {
        return Result.CONTINUE;
    }
    StepCommand<?> s = (StepCommand<?>) cmd;
    if (s.getStep() instanceof TaskCall || s.getStep() instanceof Expression) {
        return Result.CONTINUE;
    }
    ProcessDefinition pd = runtime.getService(ProcessDefinition.class);
    Location loc = s.getStep().getLocation();
    Map<String, Object> m = new HashMap<>();
    m.put("processDefinitionId", ProcessDefinitionUtils.getCurrentFlowName(pd, s.getStep()));
    m.put("fileName", loc.fileName());
    m.put("line", loc.lineNum());
    m.put("column", loc.column());
    m.put("description", getDescription(s.getStep()));
    m.put("correlationId", s.getCorrelationId());
    ProcessEventRequest req = new ProcessEventRequest();
    // TODO constants
    req.setEventType("ELEMENT");
    req.setData(m);
    req.setEventDate(Instant.now().atOffset(ZoneOffset.UTC));
    try {
        eventsApi.event(processInstanceId.getValue(), req);
    } catch (ApiException e) {
        log.warn("afterCommand [{}] -> error while sending an event to the server: {}", cmd, e.getMessage());
    }
    return Result.CONTINUE;
}
Also used : StepCommand(com.walmartlabs.concord.runtime.v2.runner.vm.StepCommand) ProcessEventRequest(com.walmartlabs.concord.client.ProcessEventRequest) HashMap(java.util.HashMap) ApiException(com.walmartlabs.concord.ApiException)

Example 12 with ProcessDefinition

use of com.walmartlabs.concord.runtime.v2.model.ProcessDefinition in project concord by walmartlabs.

the class DefaultContextFactory method create.

@Override
public Context create(Runtime runtime, State state, ThreadId currentThreadId, Step currentStep, UUID correlationId) {
    ProcessDefinition pd = runtime.getService(ProcessDefinition.class);
    Compiler compiler = runtime.getService(Compiler.class);
    ExpressionEvaluator ee = runtime.getService(ExpressionEvaluator.class);
    return new ContextImpl(compiler, ee, currentThreadId, runtime, state, pd, currentStep, correlationId, workingDirectory.getValue(), processInstanceId.getValue(), fileService, dockerService, secretService, lockService, apiConfiguration, processConfiguration);
}
Also used : Compiler(com.walmartlabs.concord.runtime.v2.sdk.Compiler) ProcessDefinition(com.walmartlabs.concord.runtime.v2.model.ProcessDefinition) ExpressionEvaluator(com.walmartlabs.concord.runtime.v2.runner.el.ExpressionEvaluator)

Example 13 with ProcessDefinition

use of com.walmartlabs.concord.runtime.v2.model.ProcessDefinition in project concord by walmartlabs.

the class FlowCallCommand method execute.

@Override
protected void execute(Runtime runtime, State state, ThreadId threadId) {
    state.peekFrame(threadId).pop();
    Context ctx = runtime.getService(Context.class);
    ExpressionEvaluator ee = runtime.getService(ExpressionEvaluator.class);
    EvalContext evalCtx = EvalContextFactory.global(ctx);
    FlowCall call = getStep();
    // the called flow's name
    String flowName = ee.eval(evalCtx, call.getFlowName(), String.class);
    // the called flow's steps
    Compiler compiler = runtime.getService(Compiler.class);
    ProcessDefinition pd = runtime.getService(ProcessDefinition.class);
    ProcessConfiguration pc = runtime.getService(ProcessConfiguration.class);
    Command steps = CompilerUtils.compile(compiler, pc, pd, flowName);
    FlowCallOptions opts = Objects.requireNonNull(call.getOptions());
    Map<String, Object> input = VMUtils.prepareInput(ee, ctx, opts.input(), opts.inputExpression());
    // the call's frame should be a "root" frame
    // all local variables will have this frame as their base
    Frame innerFrame = Frame.builder().root().commands(steps).locals(input).build();
    // an "out" handler:
    // grab the out variable from the called flow's frame
    // and put it into the callee's frame
    Command processOutVars;
    if (!opts.outExpr().isEmpty()) {
        processOutVars = new EvalVariablesCommand(ctx, opts.outExpr(), innerFrame);
    } else {
        processOutVars = new CopyVariablesCommand(opts.out(), innerFrame, VMUtils::assertNearestRoot);
    }
    // push the out handler first so it executes after the called flow's frame is done
    state.peekFrame(threadId).push(processOutVars);
    state.pushFrame(threadId, innerFrame);
}
Also used : EvalContext(com.walmartlabs.concord.runtime.v2.runner.el.EvalContext) Context(com.walmartlabs.concord.runtime.v2.sdk.Context) Compiler(com.walmartlabs.concord.runtime.v2.sdk.Compiler) FlowCall(com.walmartlabs.concord.runtime.v2.model.FlowCall) EvalContext(com.walmartlabs.concord.runtime.v2.runner.el.EvalContext) ProcessDefinition(com.walmartlabs.concord.runtime.v2.model.ProcessDefinition) ExpressionEvaluator(com.walmartlabs.concord.runtime.v2.runner.el.ExpressionEvaluator) FlowCallOptions(com.walmartlabs.concord.runtime.v2.model.FlowCallOptions) ProcessConfiguration(com.walmartlabs.concord.runtime.v2.sdk.ProcessConfiguration)

Example 14 with ProcessDefinition

use of com.walmartlabs.concord.runtime.v2.model.ProcessDefinition in project concord by walmartlabs.

the class Run method call.

@Override
public Integer call() throws Exception {
    sourceDir = sourceDir.normalize().toAbsolutePath();
    Path targetDir;
    if (Files.isRegularFile(sourceDir)) {
        Path src = sourceDir.toAbsolutePath();
        System.out.println("Running a single Concord file: " + src);
        targetDir = Files.createTempDirectory("payload");
        Files.copy(src, targetDir.resolve("concord.yml"), StandardCopyOption.REPLACE_EXISTING);
    } else if (Files.isDirectory(sourceDir)) {
        targetDir = sourceDir.resolve("target");
        if (cleanup && Files.exists(targetDir)) {
            if (verbose) {
                System.out.println("Cleaning target directory");
            }
            IOUtils.deleteRecursively(targetDir);
        }
        // copy everything into target except target
        IOUtils.copy(sourceDir, targetDir, "^target$", new CopyNotifier(verbose ? 0 : 100), StandardCopyOption.REPLACE_EXISTING);
    } else {
        throw new IllegalArgumentException("Not a directory or single Concord YAML file: " + sourceDir);
    }
    DependencyManager dependencyManager = initDependencyManager();
    ImportManager importManager = new ImportManagerFactory(dependencyManager, new CliRepositoryExporter(repoCacheDir), Collections.emptySet()).create();
    ProjectLoaderV2.Result loadResult;
    try {
        loadResult = new ProjectLoaderV2(importManager).load(targetDir, new CliImportsNormalizer(importsSource, verbose, defaultVersion), verbose ? new CliImportsListener() : null);
    } catch (ImportProcessingException e) {
        ObjectMapper om = new ObjectMapper();
        System.err.println("Error while processing import " + om.writeValueAsString(e.getImport()) + ": " + e.getMessage());
        return -1;
    } catch (Exception e) {
        System.err.println("Error while loading " + targetDir);
        e.printStackTrace();
        return -1;
    }
    ProcessDefinition processDefinition = loadResult.getProjectDefinition();
    UUID instanceId = UUID.randomUUID();
    if (verbose && !extraVars.isEmpty()) {
        System.out.println("Additional variables: " + extraVars);
    }
    if (verbose && !profiles.isEmpty()) {
        System.out.println("Active profiles: " + profiles);
    }
    ProcessConfiguration cfg = from(processDefinition.configuration()).entryPoint(entryPoint).instanceId(instanceId).build();
    RunnerConfiguration runnerCfg = RunnerConfiguration.builder().dependencies(new DependencyResolver(dependencyManager, verbose).resolveDeps(processDefinition)).debug(cfg.debug()).build();
    Map<String, Object> profileArgs = getProfilesArguments(processDefinition, profiles);
    Map<String, Object> args = ConfigurationUtils.deepMerge(cfg.arguments(), profileArgs, extraVars);
    if (verbose) {
        System.out.println("Process arguments: " + args);
    }
    args.put(Constants.Context.TX_ID_KEY, instanceId.toString());
    args.put(Constants.Context.WORK_DIR_KEY, targetDir.toAbsolutePath().toString());
    if (effectiveYaml) {
        Map<String, List<Step>> flows = new HashMap<>(processDefinition.flows());
        for (String ap : profiles) {
            Profile p = processDefinition.profiles().get(ap);
            if (p != null) {
                flows.putAll(p.flows());
            }
        }
        ProcessDefinition pd = ProcessDefinition.builder().from(processDefinition).configuration(ProcessDefinitionConfiguration.builder().from(processDefinition.configuration()).arguments(args).build()).flows(flows).imports(Imports.builder().build()).profiles(Collections.emptyMap()).build();
        ProjectSerializerV2 serializer = new ProjectSerializerV2();
        serializer.write(pd, System.out);
        return 0;
    }
    System.out.println("Starting...");
    Injector injector = new InjectorFactory(new WorkingDirectory(targetDir), runnerCfg, () -> cfg, new ProcessDependenciesModule(targetDir, runnerCfg.dependencies(), cfg.debug()), new CliServicesModule(secretStoreDir, targetDir, new VaultProvider(vaultDir, vaultId), dependencyManager)).create();
    Runner runner = injector.getInstance(Runner.class);
    if (cfg.debug()) {
        System.out.println("Available tasks: " + injector.getInstance(TaskProviders.class).names());
    }
    try {
        runner.start(cfg, processDefinition, args);
    } catch (Exception e) {
        if (verbose) {
            System.err.print("Error: ");
            e.printStackTrace(System.err);
        } else {
            System.err.println("Error: " + e.getMessage());
        }
        return 1;
    }
    System.out.println("...done!");
    return 0;
}
Also used : ImportManager(com.walmartlabs.concord.imports.ImportManager) Runner(com.walmartlabs.concord.runtime.v2.runner.Runner) DependencyManager(com.walmartlabs.concord.dependencymanager.DependencyManager) ProcessDefinition(com.walmartlabs.concord.runtime.v2.model.ProcessDefinition) Profile(com.walmartlabs.concord.runtime.v2.model.Profile) ProjectSerializerV2(com.walmartlabs.concord.runtime.v2.ProjectSerializerV2) ImmutableProcessConfiguration(com.walmartlabs.concord.runtime.v2.sdk.ImmutableProcessConfiguration) ProcessConfiguration(com.walmartlabs.concord.runtime.v2.sdk.ProcessConfiguration) InjectorFactory(com.walmartlabs.concord.runtime.v2.runner.InjectorFactory) Injector(com.google.inject.Injector) RunnerConfiguration(com.walmartlabs.concord.runtime.common.cfg.RunnerConfiguration) ImportManagerFactory(com.walmartlabs.concord.imports.ImportManagerFactory) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) Path(java.nio.file.Path) WorkingDirectory(com.walmartlabs.concord.runtime.v2.sdk.WorkingDirectory) ImportProcessingException(com.walmartlabs.concord.imports.ImportProcessingException) ProcessDependenciesModule(com.walmartlabs.concord.runtime.v2.runner.guice.ProcessDependenciesModule) IOException(java.io.IOException) ImportProcessingException(com.walmartlabs.concord.imports.ImportProcessingException) ProjectLoaderV2(com.walmartlabs.concord.runtime.v2.ProjectLoaderV2) TaskProviders(com.walmartlabs.concord.runtime.v2.runner.tasks.TaskProviders)

Example 15 with ProcessDefinition

use of com.walmartlabs.concord.runtime.v2.model.ProcessDefinition in project concord by walmartlabs.

the class ProjectLoaderV2Test method testMultiProjectFiles.

@Test
@SuppressWarnings("unchecked")
public void testMultiProjectFiles() throws Exception {
    ProjectLoaderV2 loader = new ProjectLoaderV2(mock(ImportManager.class));
    URI uri = ClassLoader.getSystemResource("multiProjectFile").toURI();
    ProjectLoaderV2.Result result = loader.load(Paths.get(uri), new NoopImportsNormalizer(), ImportsListener.NOP_LISTENER);
    assertNotNull(result);
    assertNotNull(result.getProjectDefinition());
    ProcessDefinition pd = result.getProjectDefinition();
    // configuration:
    ProcessDefinitionConfiguration cfg = pd.configuration();
    assertNotNull(cfg);
    // configuration.debug: should be collected from ROOT concord.yml
    assertTrue(cfg.debug());
    // configuration.activeProfiles: should be collected from ROOT concord.yml
    assertEquals(Collections.singletonList("concord.yml"), cfg.activeProfiles());
    // configuration.entryPoint: should be collected from ROOT concord.yml
    assertEquals("root", cfg.entryPoint());
    // configuration.dependencies: should be collected from ALL *.concord.yml
    assertEquals(Arrays.asList("2.concord.yml", "concord.yml"), cfg.dependencies());
    // configuration.arguments: should be collected from ALL *.concord.yml and mereged
    assertEquals("ttt", cfg.arguments().get("abc"));
    assertEquals("234", ((Map<String, Object>) cfg.arguments().get("nested")).get("value"));
    // configuration.meta: should be collected from ROOT concord.yml
    assertEquals(Collections.singletonMap("k", "concord.yml"), cfg.meta());
    // configuration.events: should be collected from ROOT concord.yml
    assertEquals(EventConfiguration.builder().recordTaskInVars(true).recordTaskOutVars(true).truncateInVars(true).truncateOutVars(true).truncateMaxStringLength(1).truncateMaxArrayLength(2).truncateMaxDepth(3).inVarsBlacklist(Arrays.asList("apiKey", "apiRootToken")).recordTaskMeta(true).truncateMeta(true).build(), cfg.events());
    // configuration.requirements: should be collected from ROOT concord.yml
    assertEquals(Collections.singletonMap("req", "concord.yml"), cfg.requirements());
    // configuration.processTimeout: should be collected from ROOT concord.yml
    assertEquals("PT1H", cfg.processTimeout().toString());
    // configuration.suspendTimeout: should be collected from ROOT concord.yml
    assertEquals("PT26H", cfg.suspendTimeout().toString());
    // configuration.out: should be collected from ROOT concord.yml
    assertEquals(Collections.singletonList("from-root"), cfg.out());
    // configuration.template: should be collected from ROOT concord.yml
    assertNotNull(cfg.template());
    assertEquals("mytemplate", cfg.template());
    // flows: should be collected from ALL *.concord.yml
    // if flow has same name then most recent used
    assertEquals(new HashSet<>(Arrays.asList("default", "flowN3")), pd.flows().keySet());
    assertEquals(1, pd.flows().get("default").size());
    assertTrue(pd.flows().get("default").get(0) instanceof Checkpoint);
    assertEquals("root", ((Checkpoint) pd.flows().get("default").get(0)).getName());
    // publicFlows: should be collected from ROOT concord.yml
    assertEquals(Collections.singleton("root"), pd.publicFlows());
    // profiles: should be collected from ALL *.concord.yml
    // if profile has same name then most recent used
    assertEquals(Collections.emptyMap(), pd.profiles());
    // triggers: should be collected from ALL *.concord.yml
    assertEquals(3, pd.triggers().size());
    assertEquals(Arrays.asList("1.concord.yml", "2.concord.yml", "concord.yml"), pd.triggers().stream().map(t -> t.configuration().get("entryPoint")).collect(Collectors.toList()));
    // imports: should be collected from ALL *.concord.yml
    assertEquals(2, pd.imports().items().size());
    assertEquals(Arrays.asList("2.concord.yml", "concord.yml"), pd.imports().items().stream().map(i -> ((Import.GitDefinition) i).url()).collect(Collectors.toList()));
    // forms: should be collected from ALL *.concord.yml
    // if form has same name then most recent used
    assertEquals(1, pd.forms().size());
    assertNotNull(pd.forms().get("myForm"));
    assertEquals(1, pd.forms().get("myForm").fields().size());
    assertEquals("myName3", pd.forms().get("myForm").fields().get(0).name());
    // resources: should be collected from ALL *.concord.yml
    assertEquals(Arrays.asList("glob:concord/{**/,}{*.,}concord.{yml,yaml}", "glob:tmp/1.yml"), pd.resources().concord());
}
Also used : ImportManager(com.walmartlabs.concord.imports.ImportManager) ProcessDefinitionConfiguration(com.walmartlabs.concord.runtime.v2.model.ProcessDefinitionConfiguration) ProjectLoaderV2(com.walmartlabs.concord.runtime.v2.ProjectLoaderV2) Checkpoint(com.walmartlabs.concord.runtime.v2.model.Checkpoint) Import(com.walmartlabs.concord.imports.Import) NoopImportsNormalizer(com.walmartlabs.concord.runtime.v2.NoopImportsNormalizer) ProcessDefinition(com.walmartlabs.concord.runtime.v2.model.ProcessDefinition) URI(java.net.URI) Test(org.junit.jupiter.api.Test)

Aggregations

ProcessDefinition (com.walmartlabs.concord.runtime.v2.model.ProcessDefinition)6 ExpressionEvaluator (com.walmartlabs.concord.runtime.v2.runner.el.ExpressionEvaluator)5 ProjectLoaderV2 (com.walmartlabs.concord.runtime.v2.ProjectLoaderV2)4 ImportManager (com.walmartlabs.concord.imports.ImportManager)3 TaskCallInterceptor (com.walmartlabs.concord.runtime.v2.runner.tasks.TaskCallInterceptor)3 TaskProviders (com.walmartlabs.concord.runtime.v2.runner.tasks.TaskProviders)3 Context (com.walmartlabs.concord.runtime.v2.sdk.Context)3 ProcessConfiguration (com.walmartlabs.concord.runtime.v2.sdk.ProcessConfiguration)3 Imports (com.walmartlabs.concord.imports.Imports)2 NoopImportsNormalizer (com.walmartlabs.concord.runtime.v2.NoopImportsNormalizer)2 YamlParserV2 (com.walmartlabs.concord.runtime.v2.parser.YamlParserV2)2 EvalContext (com.walmartlabs.concord.runtime.v2.runner.el.EvalContext)2 CallContext (com.walmartlabs.concord.runtime.v2.runner.tasks.TaskCallInterceptor.CallContext)2 TaskException (com.walmartlabs.concord.runtime.v2.runner.tasks.TaskException)2 Compiler (com.walmartlabs.concord.runtime.v2.sdk.Compiler)2 Frame (com.walmartlabs.concord.svm.Frame)2 URI (java.net.URI)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 Injector (com.google.inject.Injector)1 ApiException (com.walmartlabs.concord.ApiException)1