io.spikex.filter.internal.FiltersConfig.java Source code

Java tutorial

Introduction

Here is the source code for io.spikex.filter.internal.FiltersConfig.java

Source

/**
 *
 * Copyright (c) 2015 NG Modular Oy.
 *
 * 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 io.spikex.filter.internal;

import com.eaio.uuid.UUID;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import io.spikex.core.AbstractConfig;
import static io.spikex.core.AbstractFilter.CONF_KEY_CHAIN_NAME;
import io.spikex.core.util.resource.YamlDocument;
import io.spikex.core.util.resource.YamlResource;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.vertx.java.core.json.JsonObject;

/**
 *
 * @author cli
 */
public final class FiltersConfig extends AbstractConfig {

    // Available filters
    private final List<FilterDef> m_filters;

    // Filter chains
    private final List<ChainDef> m_chains;

    private static final String CONF_KEY_ALIAS = "alias";
    private static final String CONF_KEY_CHAIN = "chain";
    private static final String CONF_KEY_CHAINS = "chains";
    private static final String CONF_KEY_CONFIG = "config";
    private static final String CONF_KEY_FILTER = "filter";
    private static final String CONF_KEY_FILTERS = "filters";
    private static final String CONF_KEY_INSTANCES = "instances";
    private static final String CONF_KEY_MODULE = "module";
    private static final String CONF_KEY_MODULES = "modules";
    private static final String CONF_KEY_MULTI_THREADED = "multi-threaded";
    private static final String CONF_KEY_VERTICLE = "verticle";
    private static final String CONF_KEY_WORKER = "worker";

    private static final String ALIAS_INPUT_ADDRESS = "%InputAddress";
    private static final String ALIAS_OUTPUT_ADDRESS = "%OutputAddress";

    public FiltersConfig(final String filename, final Path path) {

        super(filename, path);
        m_filters = new ArrayList();
        m_chains = new ArrayList();
    }

    public List<FilterDef> getFilters() {
        return m_filters;
    }

    public List<ChainDef> getChains() {
        return m_chains;
    }

    public void logInputOutputDef() {

        for (ChainDef chain : getChains()) {

            logger().debug("Input/output of chain: {}", chain.getName());
            for (FilterDef filter : chain.getFilters()) {

                String alias = filter.getAlias();
                String inputAddress = filter.getInputAddress();
                String outputAddress = filter.getOutputAddress();

                if (Strings.isNullOrEmpty(outputAddress)) {
                    logger().debug("{} -> [{}]", inputAddress, alias);
                } else if (Strings.isNullOrEmpty(inputAddress)) {
                    logger().debug("[{}] -> {}", alias, outputAddress);
                } else if (Strings.isNullOrEmpty(inputAddress) && Strings.isNullOrEmpty(outputAddress)) {
                    logger().debug("[{}]", alias);
                } else {
                    logger().debug("{} -> [{}] -> {}", inputAddress, alias, outputAddress);
                }
            }
        }
    }

    @Override
    protected void build(final YamlResource resource) {
        buildFilters(resource);
        buildChains(resource);
    }

    private void buildFilters(final YamlResource resource) {

        m_filters.clear();
        List<YamlDocument> documents = resource.getData();
        if (documents != null && !documents.isEmpty()) {

            YamlDocument conf = documents.get(0);
            List<Map> modules = conf.getList(CONF_KEY_MODULES, new ArrayList());

            for (Map module : modules) {
                String groupArtifactId = (String) module.get(CONF_KEY_MODULE);
                Preconditions.checkNotNull(groupArtifactId, "Missing module");
                logger().debug("Module: {}", groupArtifactId);
                List<Map> filters = (List) module.get(CONF_KEY_FILTERS);

                for (Map<String, String> filter : filters) {
                    String alias = filter.get(CONF_KEY_ALIAS);
                    String verticle = filter.get(CONF_KEY_VERTICLE);

                    //
                    // Sanity checks
                    //
                    Preconditions.checkNotNull(alias, "Missing alias");
                    Preconditions.checkNotNull(verticle, "Missing verticle");

                    logger().debug("Filter: {} verticle: {}", alias, verticle);
                    m_filters.add(new FilterDef(groupArtifactId, alias, verticle));
                }
            }
        }
    }

    private void buildChains(final YamlResource resource) {

        m_chains.clear();
        List<YamlDocument> documents = resource.getData();
        if (documents != null && !documents.isEmpty()) {

            YamlDocument conf = documents.get(0);
            List<Map> chains = conf.getList(CONF_KEY_CHAINS, new ArrayList());
            for (Map chainMap : chains) {

                String name = (String) chainMap.get(CONF_KEY_CHAIN);
                Preconditions.checkNotNull(name, "Missing chain");
                logger().info("Found chain: {}", name);
                ChainDef chain = new ChainDef(name);
                String chainInputAddress = "";
                String chainOutputAddress = "";

                {
                    List<Map> filters = (List) chainMap.get(CONF_KEY_FILTERS);
                    for (Map filterMap : filters) {
                        String alias = (String) filterMap.get(CONF_KEY_FILTER);
                        logger().info("Filter map: {}", filterMap);

                        if (filterMap.containsKey(ALIAS_INPUT_ADDRESS)) {
                            alias = ALIAS_INPUT_ADDRESS;
                        }

                        if (filterMap.containsKey(ALIAS_OUTPUT_ADDRESS)) {
                            alias = ALIAS_OUTPUT_ADDRESS;
                        }

                        Preconditions.checkNotNull(alias, "Missing alias");

                        //
                        // Handle filter configurations
                        //
                        switch (alias) {

                        case ALIAS_INPUT_ADDRESS:
                            chainInputAddress = (String) filterMap.get(ALIAS_INPUT_ADDRESS);
                            break;

                        case ALIAS_OUTPUT_ADDRESS:
                            chainOutputAddress = (String) filterMap.get(ALIAS_OUTPUT_ADDRESS);
                            break;

                        default:
                            FilterDef filter = findFilterCopy(name, alias);
                            Preconditions.checkNotNull(filter,
                                    "Could not find matching filter definition: " + alias);

                            Map config = (Map) filterMap.get(CONF_KEY_CONFIG);
                            config.put(CONF_KEY_CHAIN_NAME, name);
                            filter.setConfig(config);

                            //
                            // worker, multi-threaded and instances
                            //
                            if (filterMap.containsKey(CONF_KEY_WORKER)) {
                                filter.setWorker((Boolean) filterMap.get(CONF_KEY_WORKER));
                            }
                            if (filterMap.containsKey(CONF_KEY_MULTI_THREADED)) {
                                filter.setMultiThreaded((Boolean) filterMap.get(CONF_KEY_MULTI_THREADED));
                            }
                            if (filterMap.containsKey(CONF_KEY_INSTANCES)) {
                                filter.setInstances((Integer) filterMap.get(CONF_KEY_INSTANCES));
                            }

                            chain.addFilter(filter);
                            break;
                        }
                    }
                }
                {
                    //
                    // Set the output address of each filter
                    //
                    String outputAddress = "";
                    List<FilterDef> filters = chain.getFilters();
                    for (FilterDef filter : Lists.reverse(filters)) {
                        if (!Strings.isNullOrEmpty(outputAddress)) {
                            filter.setOutputAddress(outputAddress);
                        }
                        outputAddress = filter.getInputAddress();
                    }
                }
                //
                // Redirect input/output
                //
                if (!Strings.isNullOrEmpty(chainInputAddress)) {
                    chain.setInputAddress(chainInputAddress);
                }
                if (!Strings.isNullOrEmpty(chainOutputAddress)) {
                    chain.setOutputAddress(chainOutputAddress);
                }

                m_chains.add(chain);
            }
        }
    }

    private FilterDef findFilterCopy(final String name, final String alias) {

        FilterDef filter = null;
        for (FilterDef tmpFilter : m_filters) {
            if (alias.equals(tmpFilter.getAlias())) {
                filter = tmpFilter.copy(name);
            }
        }
        return filter;
    }

    public static final class ChainDef {

        private final String m_name;
        private final List<FilterDef> m_filters;

        private ChainDef(final String name) {
            m_name = name;
            m_filters = new ArrayList();
        }

        public String getName() {
            return m_name;
        }

        public List<FilterDef> getFilters() {
            return m_filters;
        }

        public void addFilter(final FilterDef filter) {
            m_filters.add(filter);
        }

        public void clear() {
            m_filters.clear();
        }

        public void setInputAddress(final String address) {
            //
            // Change the input address of the first filter
            //
            if (m_filters.size() > 0) {
                FilterDef filter = m_filters.get(0);
                filter.setInputAddress(address);
            }
        }

        public void setOutputAddress(final String address) {
            //
            // Change the output address of the last filter
            //
            if (m_filters.size() > 0) {
                int lastIndex = m_filters.size() - 1;
                FilterDef filter = m_filters.get(lastIndex);
                filter.setOutputAddress(address);
            }
        }
    }

    public static final class FilterDef {

        private final String m_id;
        private final String m_module;
        private final String m_chain;
        private final String m_alias;
        private final String m_verticle;
        private Map m_config;
        private String m_inputAddress;
        private String m_outputAddress;
        private String m_deploymentId;
        private int m_instances;
        private boolean m_worker;
        private boolean m_multiThreaded;

        private FilterDef(final String alias) {
            this(alias, alias, alias, alias);
        }

        private FilterDef(final String module, final String alias, final String verticle) {
            this(module, "", alias, verticle);
        }

        private FilterDef(final String module, final String chain, final String alias, final String verticle) {

            m_id = new UUID().toString();
            m_module = module;
            m_chain = chain;
            m_alias = alias;
            m_verticle = verticle;

            StringBuilder addr = new StringBuilder(chain.toLowerCase());
            addr.append(".");
            addr.append(alias.toLowerCase());

            m_inputAddress = addr.toString();
            m_outputAddress = ""; // No output messages by default
            m_deploymentId = "";
            m_instances = 1;
            m_worker = false;
            m_multiThreaded = false;
        }

        public FilterDef copy(final String chain) {
            FilterDef copy = new FilterDef(m_module, chain, m_alias, m_verticle);
            copy.setConfig(m_config);
            return copy;
        }

        public boolean isWorker() {
            return m_worker;
        }

        public boolean isMultiThreaded() {
            return m_multiThreaded;
        }

        public boolean isDeployed() {
            return !Strings.isNullOrEmpty(m_deploymentId);
        }

        public String getId() {
            return m_id;
        }

        public String getDeploymentId() {
            return m_deploymentId;
        }

        public String getChain() {
            return m_chain;
        }

        public String getAlias() {
            return m_alias;
        }

        public String getModule() {
            return m_module;
        }

        public String getVerticle() {
            return m_verticle;
        }

        public Map getConfig() {
            return m_config;
        }

        public JsonObject getJsonConfig() {
            return new JsonObject(m_config);
        }

        public String getInputAddress() {
            return m_inputAddress;
        }

        public String getOutputAddress() {
            return m_outputAddress;
        }

        public int getInstances() {
            return m_instances;
        }

        public void setConfig(final Map config) {
            m_config = config;
        }

        public void setInputAddress(final String address) {
            m_inputAddress = address;
        }

        public void setOutputAddress(final String address) {
            m_outputAddress = address;
        }

        public void setDeploymentId(final String deploymentId) {
            m_deploymentId = deploymentId;
        }

        public void setWorker(final boolean worker) {
            m_worker = worker;
        }

        public void setMultiThreaded(final boolean multiThreaded) {
            m_multiThreaded = multiThreaded;
        }

        public void setInstances(final int instances) {
            m_instances = instances;
        }
    }
}