All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.cafdataprocessing.workflow.WorkflowManager Maven / Gradle / Ivy

There is a newer version: 7.1.0-1414
Show newest version
/*
 * Copyright 2017-2024 Open Text.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.github.cafdataprocessing.workflow;

import com.github.cafdataprocessing.workflow.model.Action;
import com.github.cafdataprocessing.workflow.model.Workflow;
import com.google.common.base.Strings;
import com.google.common.io.Resources;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.hpe.caf.api.ConfigurationException;
import com.hpe.caf.api.worker.DataStore;
import com.hpe.caf.api.worker.DataStoreException;
import com.hpe.caf.worker.document.model.Application;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yaml.snakeyaml.Yaml;

import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WorkflowManager {

    private static final Logger LOG = LoggerFactory.getLogger(WorkflowManager.class);

    private final Map workflows;
    private final DataStore dataStore;

    public WorkflowManager(final Application application, final String workflowDirectory, final String contextScriptFilePath)
                           throws ConfigurationException {
        dataStore = application.getService(DataStore.class);
        workflows = getWorkflows(workflowDirectory, contextScriptFilePath);
    }

    public Workflow get(final String workflowName){
        return workflows.get(workflowName);
    }

    private static File getContextScriptFile(final String contextScriptFilePath) {
        return contextScriptFilePath != null ? new File(contextScriptFilePath) : null;
    }

    private Map getWorkflows(final String workflowsDirectory, final String contextScriptFilePath)
            throws ConfigurationException {

        final Map workflowMap = new HashMap<>();
        final Yaml yaml = new Yaml();
        final Gson gson = new GsonBuilder().registerTypeAdapter(Action.class, new ActionTypeAdapter())
            .setPrettyPrinting().create();

        final File dir = new File(workflowsDirectory);
        if(Strings.isNullOrEmpty(dir.toString())){
            throw new ConfigurationException(String.format("No workflows found in [%s].", workflowsDirectory));
        }
        final File contextScriptFile = getContextScriptFile(contextScriptFilePath);
        final FilenameFilter filter = (final File dir1, final String name) -> name.endsWith(".yaml");
        for (final File workflowFile : dir.listFiles(filter)) {

            if(!workflowFile.exists()){
                throw new RuntimeException(String.format("File [%s] does not exist.",
                        workflowFile.toPath().toAbsolutePath()));
            }

            try (final FileInputStream fis = new FileInputStream(workflowFile)) {
                final Workflow workflow = yaml.loadAs(fis, Workflow.class);

                validateWorkflow(workflow);

                final StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.append(String.format("var ACTIONS = %s;\n", gson.toJson(workflow.getActions())));

                final String contextScriptFileContent;
                if (contextScriptFile != null) {
                    if (contextScriptFile.exists()) {
                        contextScriptFileContent = FileUtils.readFileToString(contextScriptFile,
                                                                                           StandardCharsets.UTF_8);
                        stringBuilder.append(contextScriptFileContent);
                    } else {
                        LOG.warn("The context script file from the path {} does not exist.", contextScriptFilePath);
                        contextScriptFileContent = null;
                    }
                } else {
                    contextScriptFileContent = null;
                }

                try {
                    stringBuilder.append(Resources.toString(Resources.getResource("workflow-control.js"),
                            StandardCharsets.UTF_8));
                } catch (final IOException e) {
                    throw new RuntimeException("Could not obtain workflow-control.js");
                }

                try {
                    final String addFailures = Resources.toString(Resources.getResource("add-failures.js"),
                            StandardCharsets.UTF_8).replaceAll("`", "\\`");
                    stringBuilder.append("thisScriptObject = String.raw`\n").append(addFailures);
                    if(contextScriptFileContent != null) {
                        stringBuilder.append(contextScriptFileContent);
                    }
                    stringBuilder.append("\n`;");
                } catch (final IOException e) {
                    throw new RuntimeException("Could not obtain add add-failures.js");
                }

                workflow.setWorkflowScript(stringBuilder.toString());

                workflow.setStorageReference(
                        dataStore.store(workflow.getWorkflowScript().getBytes(StandardCharsets.UTF_8),
                                "workflow-scripts"));

                final String entryname = workflowFile.getName().replaceAll(".yaml$", "");
                workflowMap.put(entryname, workflow);
            }
            catch(final IOException ex){
                throw new ConfigurationException(
                        String.format("Could not access workflow [%s] in configured directory.",
                                workflowFile.toPath().toAbsolutePath(), ex));
            }
            catch (final DataStoreException ex){
                throw new ConfigurationException("Could not store workflow in configured datastore.", ex);
            }
        }

        if(workflowMap.isEmpty()){
            throw new ConfigurationException("No workflows available.");
        }

        return workflowMap;
    }

    private static void validateWorkflow(final Workflow workflow) throws ConfigurationException {

        final List actionNames = new ArrayList<>();
        for(int index = 0; index < workflow.getActions().size(); index ++) {
            final Action action = workflow.getActions().get(index);
            if(Strings.isNullOrEmpty(action.getName())){
                throw new ConfigurationException(String.format("Action name is not defined for action [%s].", index));
            }
            if(actionNames.contains(action.getName())){
                throw new ConfigurationException(String.format("Duplicated action name [%s].", action.getName()));
            }
            actionNames.add(action.getName());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy