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

io.vanillabp.springboot.adapter.VanillaBpProperties Maven / Gradle / Ivy

There is a newer version: 1.1.3
Show newest version
package io.vanillabp.springboot.adapter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@ConfigurationProperties(prefix = VanillaBpProperties.PREFIX, ignoreUnknownFields = true)
public class VanillaBpProperties {

    private static final Logger logger = LoggerFactory.getLogger(VanillaBpProperties.class);

    public static final String PREFIX = "vanillabp";

    private List defaultAdapter = List.of();

    private Map workflowModules = Map.of();

    public Map getWorkflowModules() {
        return workflowModules;
    }

    public void setWorkflowModules(Map workflowModules) {

        this.workflowModules = workflowModules;
        workflowModules.forEach((workflowModuleId, properties) -> {
            properties.workflowModuleId = workflowModuleId;
            properties.defaultProperties = this;
        });

    }

    public List getDefaultAdapter() { return defaultAdapter; }

    public void setDefaultAdapter(List defaultAdapter) { this.defaultAdapter = defaultAdapter; }

    public static class AdapterConfiguration {
        
        private String resourcesLocation;
        
        public String getResourcesLocation() {
            return resourcesLocation;
        }
        
        public void setResourcesLocation(String resourcesLocation) {
            this.resourcesLocation = resourcesLocation;
        }
        
    }

    public static class WorkflowModuleAdapterProperties extends AdapterProperties {

        String workflowModuleId;

        VanillaBpProperties defaultProperties;

        private Map adapters = Map.of();

        private Map workflows = Map.of();

        public Map getWorkflows() {
            return workflows;
        }

        public void setWorkflows(Map workflows) {

            this.workflows = workflows;
            workflows.forEach((bpmnProcessId, properties) -> {
                properties.bpmnProcessId = bpmnProcessId;
                properties.workflowModule = this;
            });

        }

        public Map getAdapters() {
            return adapters;
        }

        public void setAdapters(Map adapters) {
            this.adapters = adapters;
        }

        public String getWorkflowModuleId() {
            return workflowModuleId;
        }

        public VanillaBpProperties getDefaultProperties() {
            return defaultProperties;
        }

    }

    public static class WorkflowAdapterProperties extends AdapterProperties {

        String bpmnProcessId;

        WorkflowModuleAdapterProperties workflowModule;

        public WorkflowModuleAdapterProperties getWorkflowModule() {
            return workflowModule;
        }

        public String getBpmnProcessId() {
            return bpmnProcessId;
        }

    }

    private static class AdapterProperties {

        private List defaultAdapter = List.of();

        public List getDefaultAdapter() {
            return defaultAdapter;
        }

        public void setDefaultAdapter(List defaultAdapter) {
            this.defaultAdapter = defaultAdapter;
        }

    }

    public List getDefaultAdapterFor(
            final String workflowModuleId,
            final String bpmnProcessId) {

        var defaultAdapter = getDefaultAdapter();
        final var workflowModule = getWorkflowModules().get(workflowModuleId);
        if (workflowModule != null) {
            if (!workflowModule.getDefaultAdapter().isEmpty()) {
                defaultAdapter = workflowModule.getDefaultAdapter();
            }
            if (bpmnProcessId != null) {
                final var workflow = workflowModule.getWorkflows().get(bpmnProcessId);
                if (workflow != null) {
                    if (!workflow.getDefaultAdapter().isEmpty()) {
                        defaultAdapter = workflowModule.getDefaultAdapter();
                    }
                }
            }
        }
        return defaultAdapter;

    }

    public String getAdapterResourcesLocationFor(
            final String workflowModuleId,
            final String adapterId) {

        String resourcesLocation = null;
        final var workflowModule = getWorkflowModules().get(workflowModuleId);
        if (workflowModule != null) {
            final var adapter = workflowModule.getAdapters().get(adapterId);
            if (adapter != null) {
                resourcesLocation = adapter.getResourcesLocation();
            }
        }
        if (resourcesLocation == null) {
            throw new RuntimeException(
                    "Property '"
                    + VanillaBpProperties.PREFIX
                    + ".workflow-modules."
                    + workflowModuleId
                    + ".adapters."
                    + adapterId
                    + ".resources-location' not set!\nIt has to point to a location specific to the adapter in order "
                    + "to avoid future problems once you wish to migrate to another adapter.\nSample: '"
                    + "classpath*:/workflow-resources/"
                    + adapterId
                    + "'");
        }
        return resourcesLocation;

    }

    public void validatePropertiesFor(
            final List adapterIds,
            final String workflowModuleId,
            final String bpmnProcessId) {

        final var defaultAdapters = getDefaultAdapterFor(workflowModuleId, bpmnProcessId);
        if (defaultAdapters.isEmpty()) {
            throw new RuntimeException(
                    "More than one VanillaBP adapter was found in classpath, but no default adapter is configured at\n  "
                            + PREFIX
                            + ".workflow-modules."
                            + workflowModuleId
                            + ".workflows."
                            + bpmnProcessId
                            + ".default-adapter or \n  "
                            + PREFIX
                            + ".workflow-modules."
                            + workflowModuleId
                            + ".default-adapter or \n  "
                            + PREFIX
                            + ".default-adapter\nAvailable adapters are '"
                            + String.join("', '", adapterIds)
                            + "'.");
        }

        final var listOfAdapters = String.join("', '", adapterIds);
        final var missingAdapters = defaultAdapters
                .stream()
                .filter(defaultAdapter -> !adapterIds.contains(defaultAdapter))
                .collect(Collectors.joining("', '"));
        if (!missingAdapters.isEmpty()) {
            throw new RuntimeException(
                    "Property 'default-adapter' of workflow-module '"
                    + workflowModuleId
                    + "' and bpmn-process-id '"
                    + bpmnProcessId
                    + "' contains adapters not available in classpath:\n'  "
                    + missingAdapters
                    + "'!\nAvailable adapters are: '"
                    + listOfAdapters
                    + "'.");
        }

    }

    public void validateProperties(
            final List adapterIds,
            final List knownWorkflowModuleIds) {

        // unknown workflow-module properties
        final var configAvailableButNotInClasspath = new LinkedList<>(
                getWorkflowModules()
                .keySet());
        configAvailableButNotInClasspath
                .removeAll(knownWorkflowModuleIds);
        if (!configAvailableButNotInClasspath.isEmpty()) {
            logger.warn("Found properties for workflow-modules\n"
                    + PREFIX + ".workflow-modules."
                    + String.join(
                            "\n" + PREFIX + ".workflow-modules.",
                            configAvailableButNotInClasspath)
                    + "\nwhich were not found in the class-path!");
        }

        // adapter configured
        if (adapterIds.size() == 1) {
            logger.info(
                    "Found only one VanillaBP adapter '"
                    + adapterIds.get(0)
                    + "' in classpath. Please ensure the properties\n"
                    + PREFIX
                    + ".workflow-modules"
                    + String.join(
                            ".adapters."
                                    + adapterIds.get(0)
                                    + ".resources-location\n"
                                    + PREFIX
                                    + ".workflow-modules",
                            configAvailableButNotInClasspath)
                    + ".adapters."
                    + adapterIds.get(0)
                    + ".resources-location\nare specific for this adapter in " +
                    "order to avoid future-problems once you wish to migrate to another adapter.");
        }

        // adapters in class-path not used
        final var notConfiguredAdapters = new HashMap>() {
                @Override
                public Set get(final Object key) {
                    var adapters = super.get(key);
                    if (adapters == null) {
                        adapters = new HashSet<>();
                        super.put(key.toString(), adapters);
                    }
                    return adapters;
                }
            };
        getDefaultAdapter()
                .stream()
                .filter(adapterId -> !adapterIds.contains(adapterId))
                .forEach(adapterId -> notConfiguredAdapters.get(
                VanillaBpProperties.PREFIX
                        + ".default-adapter"
                ).add(adapterId));
        getWorkflowModules().values().forEach(workflowModule -> {
                workflowModule
                        .getDefaultAdapter()
                        .stream()
                        .filter(adapterId -> !adapterIds.contains(adapterId))
                        .forEach(adapterId -> notConfiguredAdapters.get(
                                VanillaBpProperties.PREFIX
                                        + ".workflow-modules."
                                        + workflowModule.workflowModuleId
                                        + ".default-adapter"
                        ).add(adapterId));
                workflowModule.getWorkflows().values().forEach(workflow -> {
                    workflow
                            .getDefaultAdapter()
                            .stream()
                            .filter(adapterId -> !adapterIds.contains(adapterId))
                            .forEach(adapterId -> notConfiguredAdapters.get(
                            VanillaBpProperties.PREFIX
                                    + ".workflow-modules."
                                    + workflowModule.workflowModuleId
                                    + ".workflows."
                                    + workflow.getBpmnProcessId()
                                    + ".default-adapter"
                            ).add(adapterId));
                });
            });
        if (!notConfiguredAdapters.isEmpty()) {
            throw new RuntimeException(
                    "There are VanillaBP adapters configured not found in classpath:\n"
                            + notConfiguredAdapters
                            .entrySet()
                            .stream()
                            .map(entry -> "  " + entry.getKey() + "=" + entry.getValue().stream().collect(Collectors.joining(",")))
                            .collect(Collectors.joining("\n")));
        }

        // resources-location
        knownWorkflowModuleIds
                .forEach(workflowModuleId -> {
                    final var defaultAdapterOfModule = getDefaultAdapterFor(workflowModuleId, null);
                    final var resourcesLocationOfModule = (defaultAdapterOfModule.isEmpty()
                                    ? defaultAdapter : defaultAdapterOfModule)
                            .stream()
                            .filter(adapterId -> getAdapterResourcesLocationFor(workflowModuleId, adapterId) == null)
                            .toList();
                    if (!resourcesLocationOfModule.isEmpty()) {
                        throw new RuntimeException(
                                "You need to define properties '"
                                        + PREFIX
                                        + ".workflow-modules."
                                        + workflowModuleId
                                        + ".adapters."
                                        + String.join(
                                        ".resources-location\n"
                                                + PREFIX
                                                + ".workflow-modules."
                                                + workflowModuleId
                                                + ".adapters.",
                                        defaultAdapter)
                                        + ".resources-location");
                    }
                    getBpmnProcessIdsForWorkflowModule(workflowModuleId)
                            .forEach(bpmnProcessId -> {
                                final var defaultAdapter = getDefaultAdapterFor(workflowModuleId, bpmnProcessId);
                                final var resourcesLocation = defaultAdapter
                                        .stream()
                                        .filter(adapterId -> getAdapterResourcesLocationFor(workflowModuleId, adapterId) == null)
                                        .toList();
                                if (!resourcesLocation.isEmpty()) {
                                    throw new RuntimeException(
                                            "You need to define properties '"
                                                    + PREFIX
                                                    + ".workflow-modules."
                                                    + workflowModuleId
                                                    + ".adapters."
                                                    + String.join(
                                                    ".resources-location\n"
                                                            + PREFIX
                                                            + ".workflow-modules."
                                                            + workflowModuleId
                                                            + ".adapters.",
                                                    defaultAdapter)
                                                    + ".resources-location");
                                }
                            });
                });

    }

    private List getBpmnProcessIdsForWorkflowModule(
            final String workflowModuleId) {

        final var workflowModule = getWorkflowModules().get(workflowModuleId);
        if (workflowModule == null) {
            return List.of();
        }

        return workflowModule
                .getWorkflows()
                .values()
                .stream()
                .map(WorkflowAdapterProperties::getBpmnProcessId)
                .toList();

    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy