silentbalanceyh/vertx-zero

View on GitHub
vertx-gaia/vertx-co/src/main/java/io/vertx/up/commune/Ruler.java

Summary

Maintainability
B
4 hrs
Test Coverage
package io.vertx.up.commune;

import io.horizon.eon.VPath;
import io.horizon.eon.VString;
import io.horizon.exception.ProgramException;
import io.horizon.uca.cache.Cc;
import io.horizon.uca.log.Annal;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.up.fn.Fn;
import io.vertx.up.uca.stable.ForbiddenInsurer;
import io.vertx.up.uca.stable.Insurer;
import io.vertx.up.uca.stable.RequiredInsurer;
import io.vertx.up.uca.stable.TypedInsurer;
import io.vertx.up.util.Ut;

import java.text.MessageFormat;
import java.util.Objects;
import java.util.concurrent.ConcurrentMap;

/**
 * Ruler checking for json object / json array
 */
public class Ruler {

    private static final Annal LOGGER = Annal.get(Ruler.class);

    private static final Cc<String, JsonObject> CC_RULE = Cc.open();
    private static final Cc<String, Insurer> CC_INSURER = Cc.open();


    /**
     * Verify data for each up.god.file
     *
     * @param file The rule up.god.file that input into this method.
     * @param data The data that will be verified.
     *
     * @throws ProgramException Error when verified handler.
     */
    public static void verify(final String file, final JsonObject data) throws ProgramException {
        Fn.bugAt(() -> {
            // 1. Rule for json object
            final JsonObject rule = getRule(file);
            if (Objects.isNull(rule)) {
                return;
            }
            verifyItem(data, rule);
            // 2. For json item
            for (final String field : data.fieldNames()) {
                final Object value = data.getValue(field);
                Fn.bugAt(() -> {
                    if (Ut.isJObject(value) || Ut.isJArray(value)) {
                        final String filename = file + VString.DOT + field;
                        if (Ut.isJObject(value)) {
                            // 3.1.2 Json array child
                            verify(filename, (JsonObject) value);
                        } else if (Ut.isJArray(value)) {
                            // 3.1.3 Json array child
                            verify(filename, (JsonArray) value);
                        }
                    }
                }, value);
            }
        }, file, data);
    }

    /**
     * Verify data for each up.god.file
     *
     * @param file The file that current object bind
     * @param data The data that will be verified
     *
     * @throws ProgramException Whether here throw validated exception
     */
    public static void verify(final String file, final JsonArray data) throws ProgramException {
        Fn.bugAt(() -> {
            // 1. Rule for json array
            final JsonObject rule = getRule(file);
            if (Objects.isNull(rule)) {
                return;
            }
            verifyItem(data, rule);
            // 2. For json item
            Fn.bugIt(data, (value, field) -> {
                // 3. Value = JsonObject, identify if extension.
                final String filename = file + VString.DOT + field;
                if (Ut.isJObject(value)) {
                    // JsonObject
                    verify(filename, (JsonObject) value);
                } else if (Ut.isJArray(value)) {
                    // JsonArray
                    verify(filename, (JsonArray) value);
                }
            });
        }, file, data);
    }

    private static <T> void verifyItem(final T input, final JsonObject rule) throws ProgramException {
        Fn.bugAt(() -> {

            if (Ut.isJArray(input)) {
                final JsonArray data = (JsonArray) input;
                // Required
                Insurer reference = CC_INSURER.pick(RequiredInsurer::new, "A-Required");
                // Fn.po?lThread(POOL_INSURER, RequiredInsurer::new, "A-Required");
                reference.flumen(data, rule);
                // EmType
                reference = CC_INSURER.pick(TypedInsurer::new, "A-EmType");
                // Fn.po?lThread(POOL_INSURER, TypedInsurer::new, "A-Type");
                reference.flumen(data, rule);
                // Forbidden
                reference = CC_INSURER.pick(ForbiddenInsurer::new, "A-Forbidden");
                // Fn.po?lThread(POOL_INSURER, ForbiddenInsurer::new, "A-Forbidden");
                reference.flumen(data, rule);
            } else {
                final JsonObject data = (JsonObject) input;
                // Required
                Insurer reference = CC_INSURER.pick(RequiredInsurer::new, "J-Required");
                // Fn.po?lThread(POOL_INSURER, RequiredInsurer::new, "J-Required");
                reference.flumen(data, rule);
                // EmType
                reference = CC_INSURER.pick(TypedInsurer::new, "J-Type");
                // Fn.po?lThread(POOL_INSURER, TypedInsurer::new, "J-Type");
                reference.flumen(data, rule);
                // Forbidden
                reference = CC_INSURER.pick(ForbiddenInsurer::new, "J-Forbidden");
                // Fn.po?lThread(POOL_INSURER, ForbiddenInsurer::new, "J-Forbidden");
                reference.flumen(data, rule);
            }
        }, input, rule);
    }

    private static JsonObject getRule(final String file) {
        // Cached rule into memory pool
        final String filename = MessageFormat.format(VPath.SERVER.INTERNAL_RULE, file);
        final ConcurrentMap<String, JsonObject> data = CC_RULE.store();
        if (data.containsKey(filename)) {
            LOGGER.debug(MESSAGE.Ruler.RULE_CACHED_FILE, filename);
        } else {
            LOGGER.debug(MESSAGE.Ruler.RULE_FILE, filename);
        }
        if (Ut.ioExist(filename)) {
            return CC_RULE.pick(() -> Ut.ioYaml(filename), filename);
        } else {
            return null;
        }
    }
}