Skip to content

Commit

Permalink
AOP Modify
Browse files Browse the repository at this point in the history
  • Loading branch information
silentbalanceyh committed Jun 4, 2023
1 parent cf2df95 commit b027c8f
Show file tree
Hide file tree
Showing 15 changed files with 463 additions and 140 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ public interface VName {

String LABEL = "label"; /* Common: label */
String TYPE = "type"; /* Common: type for different model */
String ROBIN = "robin";
String DEPLOY_ID = "deployID"; /* */
String ASPECT = "aspect"; /* Aspect Component Usage */
String DEPLOYMENT = "deployment"; /* */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@ public enum Effect {
AROUND, // 前后执行
NONE, // 关闭不执行
}

public enum Robin {
FIELD, // 按字段分流
COMPONENT, // 按配置的组件进行分流
NONE, // 未设置分流器
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package io.modello.eon.configure;

/**
* @author lang : 2023-06-03
*/
interface HPCAop {
import io.horizon.eon.VName;
import io.horizon.uca.aop.AspectRobin;
import io.vertx.core.json.JsonArray;

interface _HPCAopComponent {
/**
* <value>plugin.component.before</value>,AOP配置中的前置插件,数据类型为 {@link io.vertx.core.json.JsonArray}
* 配置如下:
Expand All @@ -20,7 +21,7 @@ interface HPCAop {
* Monad1 -> Monad2 -> Monad3
* 配置点有两部分:
* 1. 动态建模 {@see VDBC.I_SERVICE.SERVICE_CONFIG} 中配置
* 2. 全局处理 {@link io.horizon.uca.aop.AspectConfig} 中处理
* 2. 全局处理 {@link AspectRobin} 中处理
* </code></pre>
*/
String PLUGIN_COMPONENT_BEFORE = "plugin.component.before";
Expand All @@ -40,7 +41,7 @@ interface HPCAop {
* Monad1 -> Monad2 -> Monad3
* 配置点有两部分:
* 1. 动态建模 {@see VDBC.I_SERVICE.SERVICE_CONFIG} 中配置
* 2. 全局处理 {@link io.horizon.uca.aop.AspectConfig} 中处理
* 2. 全局处理 {@link AspectRobin} 中处理
* </code></pre>
*/
String PLUGIN_COMPONENT_AFTER = "plugin.component.after";
Expand All @@ -57,6 +58,22 @@ interface HPCAop {
* </code></pre>
*/
String PLUGIN_COMPONENT_JOB = "plugin.component.job";
}

/**
* @author lang : 2023-06-03
*/
interface HPCAop extends _HPCAopComponent {
/**
* <value>plugin.fork</value>,新追加分流器配置,针对请求数据执行分流规则,让抽象表可支持多分流模式的AOP基本规则,AOP实现模式:
* <pre><code>
* 1. 不带分流器规则
* 2. 带分流器规则:
* 1)简单规则:按照单字段数据执行分流
* 2)复杂规则:提供
* </code></pre>
*/
String PLUGIN_FORK = "plugin.fork";
/**
* <value>plugin.config</value>, 和 Before/After 相关的组件静态配置,数据类型为 {@link io.vertx.core.json.JsonObject}
*
Expand All @@ -78,4 +95,39 @@ interface HPCAop {
* 上述片段中 component1 和 component2 是组件名称(Java类全名)
*/
String PLUGIN_CONFIG = "plugin.config";

interface plugin_fork {
/**
* 分流器类型,对应 {@link io.horizon.eon.em.EmAop.Robin}
*/
String TYPE = VName.TYPE;

String ROBIN = VName.ROBIN;

String CONFIG = VName.CONFIG;

/**
* 分流之后会形成类似如下结构(不同的值使用的组件不一样)
* <pre><code>
* "value1" = {
* "plugin.component.before": [],
* "plugin.component.job": [],
* "plugin.component.after": []
* }
* </code></pre>
* 分流限制:
* <pre><code>
* 1. 每种组件的配置一致
* 2. 最好书写不同的组件做分流,而在内部逻辑中去处理共享部分
* 3. 分流依赖输入数据,现阶段不做批量分流,批量分流之后的结果依然是一个 String 的唯一 key,
* 简单讲就是调用 {@link io.horizon.util.HUt#valueSetString} 方法从 {@link JsonArray} 中提取唯一键值
* </code></pre>
*/
interface __ extends _HPCAopComponent {
}

interface config {
String BY = VName.BY;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ public class Aspect {
private final transient AspectJObject executorJ;

private Aspect(final JsonObject components) {
this.executorT = new AspectT(AspectConfig.create(components));
this.executorT = new AspectT(AspectRobin.create(components));
this.executorJ = new AspectJObject();
}

private Aspect(final AspectConfig config) {
private Aspect(final AspectRobin config) {
this.executorT = new io.horizon.uca.aop.AspectT(config);
this.executorJ = new io.horizon.uca.aop.AspectJObject();
}
Expand All @@ -38,7 +38,7 @@ public static Aspect create(final JsonObject components) {
// Fn.po?lThread(POOL_ASPECT, () -> new Aspect(config), cacheKey);
}

public static Aspect create(final AspectConfig config) {
public static Aspect create(final AspectRobin config) {
Objects.requireNonNull(config);
return CC_ASPECT.pick(() -> new Aspect(config), String.valueOf(config.hashCode()));
// Fn.po?lThread(POOL_ASPECT, () -> new Aspect(config), String.valueOf(config.hashCode()));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package io.horizon.uca.aop;

import io.horizon.util.HUt;
import io.modello.eon.configure.VPC;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;

/**
* <pre><code>
* {
* "plugin.component.before": [],
* "plugin.component.job": [],
* "plugin.component.after": []
* }
* </code></pre>
*
* @author lang : 2023-06-03
*/
class AspectComponent {

private final List<Class<?>> nameBefore = new ArrayList<>();
private final List<Class<?>> nameAfter = new ArrayList<>();
private final List<Class<?>> nameJob = new ArrayList<>();

AspectComponent(final JsonObject configuration) {
// Plugin Before
this.initialize(configuration, VPC.aop.PLUGIN_COMPONENT_BEFORE,
this.nameBefore::add,
clazz -> HUt.isImplement(clazz, Before.class) || HUt.isImplement(clazz, Around.class));

// Plugin After
this.initialize(configuration, VPC.aop.PLUGIN_COMPONENT_AFTER,
this.nameAfter::add,
clazz -> HUt.isImplement(clazz, After.class) || HUt.isImplement(clazz, Around.class));

// Plugin Job
this.initialize(configuration, VPC.aop.PLUGIN_COMPONENT_JOB,
this.nameJob::add,
clazz -> HUt.isImplement(clazz, After.class) || HUt.isImplement(clazz, Around.class));
}

private void initialize(
final JsonObject configuration, final String field,
final Consumer<Class<?>> fnConsumer,
final Predicate<Class<?>> fnCheck) {
final JsonArray source = HUt.valueJArray(configuration, field);
HUt.itJArray(source, String.class, (item, index) -> {
final Class<?> clazz = HUt.clazz(item, null);
if (Objects.nonNull(clazz) && fnCheck.test(clazz)) {
fnConsumer.accept(clazz);
}
});
}

public List<Class<?>> nameBefore() {
return this.nameBefore;
}

public List<Class<?>> nameAfter() {
return this.nameAfter;
}

public List<Class<?>> nameJob() {
return this.nameJob;
}
}
149 changes: 63 additions & 86 deletions vertx-gaia/vertx-ams/src/main/jib/io/horizon/uca/aop/AspectConfig.java
Original file line number Diff line number Diff line change
@@ -1,113 +1,90 @@
package io.horizon.uca.aop;

import io.horizon.exception.web._501NotSupportException;
import io.horizon.specification.uca.HRobin;
import io.horizon.util.HUt;
import io.modello.eon.configure.VPC;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.BiConsumer;
import java.util.function.Predicate;

/**
* The configuration data structure:
*
* @author <a href="http://www.origin-x.cn">Lang</a>
* @author lang : 2023-06-03
*/
public class AspectConfig implements Serializable {
/*
* {
* "components": {
* "plugin.component.before": [],
* "plugin.component.job": [],
* "plugin.component.after": [],
* "plugin.config": {
* }
* }
* }
*/
class AspectConfig {
private final JsonObject forkJ = new JsonObject();
private final ConcurrentMap<Class<?>, JsonObject> configMap = new ConcurrentHashMap<>();

private final List<Class<?>> nameBefore = new ArrayList<>();
private final List<Class<?>> nameAfter = new ArrayList<>();
private final List<Class<?>> nameJob = new ArrayList<>();

private AspectConfig(final JsonObject components) {
// Plugin Before
this.initialize(components, VPC.aop.PLUGIN_COMPONENT_BEFORE, (clazz, config) -> {
this.nameBefore.add(clazz);
this.configMap.put(clazz, config);
}, clazz -> HUt.isImplement(clazz, Before.class) || HUt.isImplement(clazz, io.horizon.uca.aop.Around.class));

// Plugin After
this.initialize(components, VPC.aop.PLUGIN_COMPONENT_AFTER, (clazz, config) -> {
this.nameAfter.add(clazz);
this.configMap.put(clazz, config);
}, clazz -> HUt.isImplement(clazz, After.class) || HUt.isImplement(clazz, io.horizon.uca.aop.Around.class));

// Plugin Job
this.initialize(components, VPC.aop.PLUGIN_COMPONENT_JOB, (clazz, config) -> {
this.nameJob.add(clazz);
this.configMap.put(clazz, config);
}, clazz -> HUt.isImplement(clazz, After.class) || HUt.isImplement(clazz, io.horizon.uca.aop.Around.class));
}

public static AspectConfig create(final JsonObject components) {
return new AspectConfig(components);
}

public static AspectConfig create() {
return new AspectConfig(new JsonObject());
}

private void initialize(
final JsonObject configuration, final String field,
final BiConsumer<Class<?>, JsonObject> fnConsumer,
final Predicate<Class<?>> fnCheck) {
final JsonArray source = HUt.valueJArray(configuration, field);
HUt.itJArray(source, String.class, (item, index) -> {
final Class<?> clazz = HUt.clazz(item, null);
if (Objects.nonNull(clazz) && fnCheck.test(clazz)) {
final JsonObject config = HUt.valueJObject(configuration, VPC.aop.PLUGIN_CONFIG);
final JsonObject valueJ = HUt.valueJObject(config, clazz.getName());
fnConsumer.accept(clazz, valueJ);
}
});
JsonObject config(final Class<?> clazz) {
Objects.requireNonNull(clazz);
return this.configMap.getOrDefault(clazz, new JsonObject());
}

public List<Class<?>> nameBefore() {
return this.nameBefore;
void config(final Class<?> clazz, final JsonObject config) {
Objects.requireNonNull(clazz);
this.configMap.put(clazz, HUt.isNil(config) ? new JsonObject() : config);
}

public List<Class<?>> nameAfter() {
return this.nameAfter;
void bind(final AspectComponent component, final JsonObject configJ) {
this.bind(component.nameBefore(), configJ);
this.bind(component.nameAfter(), configJ);
this.bind(component.nameJob(), configJ);
}

public List<Class<?>> nameJob() {
return this.nameJob;
void bind(final JsonObject forkJ) {
this.forkJ.mergeIn(forkJ, true);
}

public JsonObject config(final Class<?> clazz) {
Objects.requireNonNull(clazz);
return this.configMap.getOrDefault(clazz, new JsonObject());
}

public AspectConfig config(final Class<?> clazz, final JsonObject external) {
this.configMap.put(clazz, external);
return this;
/**
* 值节点选择器,主要针对
* <pre><code>
* {
* "type": "FIELD",
* "robin": "",
* "config": {
* "by": "identifier"
* }
* }
* </code></pre>
*
* @param input 输入参数(JsonObject、JsonArray、T)
* @param <T> 输入类型
*
* @return 选择计算的值
*/
<T> String forkKey(final T input) {
final Class<?> clazz = HUt.valueC(this.forkJ, VPC.aop.plugin_fork.ROBIN);
final JsonObject config = HUt.valueJObject(this.forkJ, VPC.aop.plugin_fork.CONFIG);
if (Objects.nonNull(clazz)) {
// 配置了 robin
final HRobin<T> robin = HUt.singleton(clazz);
return robin.execute(input, config);
} else {
// 未配置组件,暂时只考虑 type = FIELD 的情况
final String by = HUt.valueString(config, VPC.aop.plugin_fork.config.BY);
Objects.requireNonNull(by);
if (input instanceof JsonObject) {
final JsonObject inputJ = (JsonObject) input;
return HUt.valueString(inputJ, by);
} else if (input instanceof JsonArray) {
final JsonArray inputA = (JsonArray) input;
return HUt.valueString(inputA, by);
} else {
throw new _501NotSupportException(this.getClass());
}
}
}

@Override
public String toString() {
return "AspectConfig{" +
"nameBefore=" + this.nameBefore +
", nameAfter=" + this.nameAfter +
", nameJob=" + this.nameJob +
'}';
private void bind(final Collection<Class<?>> clazzSet, final JsonObject configJ) {
clazzSet.forEach(clazz -> {
if (configJ.containsKey(clazz.getName())) {
final JsonObject componentConfig = HUt.valueJObject(configJ, clazz.getName());
this.config(clazz, componentConfig);
}
});
}
}
Loading

0 comments on commit b027c8f

Please sign in to comment.