Support process control in aggregation #215
This commit is contained in:
@@ -190,6 +190,36 @@ var common = {
|
|||||||
}
|
}
|
||||||
var result = ctx[stepName]['result'] || {};
|
var result = ctx[stepName]['result'] || {};
|
||||||
return field ? result[field] : result;
|
return field ? result[field] : result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取步骤循环结果
|
||||||
|
* @param {*} ctx 上下文 【必填】
|
||||||
|
* @param {*} stepName 步骤名【必填】
|
||||||
|
*/
|
||||||
|
getStepCircle: function (ctx, stepName){
|
||||||
|
if(!ctx || !stepName || !ctx[stepName]){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 返回循环结果数组
|
||||||
|
return ctx[stepName]['circle'];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求的循环结果
|
||||||
|
* @param {*} ctx 上下文 【必填】
|
||||||
|
* @param {*} stepName 步骤名【必填】
|
||||||
|
*/
|
||||||
|
getRequestCircle: function (ctx, stepName, requestName){
|
||||||
|
if(!ctx || !stepName || !requestName){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if(!ctx[stepName] || !ctx[stepName]['requests'] || !ctx[stepName]['requests'][requestName] ||
|
||||||
|
!ctx[stepName]['requests'][requestName]['request']){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 返回循环结果数组
|
||||||
|
return ctx[stepName]['requests'][requestName]['circle'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *********** step request end ************ */
|
/* *********** step request end ************ */
|
||||||
|
|||||||
@@ -46,7 +46,34 @@ var context = {
|
|||||||
response: {
|
response: {
|
||||||
headers: {},
|
headers: {},
|
||||||
body: {}
|
body: {}
|
||||||
}
|
},
|
||||||
|
// 请求循环组件当前循环对象
|
||||||
|
item: null,
|
||||||
|
// 请求循环组件当前循环对象的下标
|
||||||
|
index: null,
|
||||||
|
// 请求循环的结果
|
||||||
|
circle: [{
|
||||||
|
// 循环对象
|
||||||
|
item: null,
|
||||||
|
// 循环对象的下标
|
||||||
|
index: null,
|
||||||
|
// 请求相关参数
|
||||||
|
request:{
|
||||||
|
url: "",
|
||||||
|
method: "GET/POST",
|
||||||
|
headers: {},
|
||||||
|
body: {}
|
||||||
|
},
|
||||||
|
// 根据转换规则转换后的接口响应
|
||||||
|
response: {
|
||||||
|
headers: {},
|
||||||
|
body: {}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
// 条件组件的执行结果
|
||||||
|
conditionResults: [
|
||||||
|
{'我的条件1': true}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
// 接口2
|
// 接口2
|
||||||
request2: {
|
request2: {
|
||||||
@@ -59,13 +86,52 @@ var context = {
|
|||||||
response: {
|
response: {
|
||||||
headers: {},
|
headers: {},
|
||||||
body: {}
|
body: {}
|
||||||
}
|
},
|
||||||
|
// 请求循环组件当前循环对象
|
||||||
|
item: null,
|
||||||
|
// 请求循环组件当前循环对象的下标
|
||||||
|
index: null,
|
||||||
|
// 请求循环的结果
|
||||||
|
circle: [{
|
||||||
|
// 循环对象
|
||||||
|
item: null,
|
||||||
|
// 循环对象的下标
|
||||||
|
index: null,
|
||||||
|
// 请求相关参数
|
||||||
|
request:{
|
||||||
|
url: "",
|
||||||
|
method: "GET/POST",
|
||||||
|
headers: {},
|
||||||
|
body: {}
|
||||||
|
},
|
||||||
|
// 根据转换规则转换后的接口响应
|
||||||
|
response: {
|
||||||
|
headers: {},
|
||||||
|
body: {}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
// 条件组件的执行结果
|
||||||
|
conditionResults: [
|
||||||
|
{'我的条件1': true}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
//...
|
//...
|
||||||
},
|
},
|
||||||
|
|
||||||
// 步骤结果
|
// 步骤结果
|
||||||
result: {}
|
result: {},
|
||||||
|
// 步骤循环组件当前循环对象
|
||||||
|
item: null,
|
||||||
|
// 步骤循环组件当前循环对象的下标
|
||||||
|
index: null,
|
||||||
|
// 步骤循环的结果
|
||||||
|
circle:[{
|
||||||
|
// 循环对象
|
||||||
|
item: null,
|
||||||
|
// 循环对象的下标
|
||||||
|
index: null,
|
||||||
|
// 步骤结果
|
||||||
|
result: {}
|
||||||
|
}]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,6 +190,36 @@ var common = {
|
|||||||
}
|
}
|
||||||
var result = ctx[stepName]['result'] || {};
|
var result = ctx[stepName]['result'] || {};
|
||||||
return field ? result[field] : result;
|
return field ? result[field] : result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取步骤循环结果
|
||||||
|
* @param {*} ctx 上下文 【必填】
|
||||||
|
* @param {*} stepName 步骤名【必填】
|
||||||
|
*/
|
||||||
|
getStepCircle: function (ctx, stepName){
|
||||||
|
if(!ctx || !stepName || !ctx[stepName]){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 返回循环结果数组
|
||||||
|
return ctx[stepName]['circle'];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取请求的循环结果
|
||||||
|
* @param {*} ctx 上下文 【必填】
|
||||||
|
* @param {*} stepName 步骤名【必填】
|
||||||
|
*/
|
||||||
|
getRequestCircle: function (ctx, stepName, requestName){
|
||||||
|
if(!ctx || !stepName || !requestName){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if(!ctx[stepName] || !ctx[stepName]['requests'] || !ctx[stepName]['requests'][requestName] ||
|
||||||
|
!ctx[stepName]['requests'][requestName]['request']){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 返回循环结果数组
|
||||||
|
return ctx[stepName]['requests'][requestName]['circle'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *********** step request end ************ */
|
/* *********** step request end ************ */
|
||||||
|
|||||||
@@ -119,12 +119,12 @@ public class Pipeline {
|
|||||||
}else {
|
}else {
|
||||||
LinkedList<Step> opSteps = (LinkedList<Step>) steps.clone();
|
LinkedList<Step> opSteps = (LinkedList<Step>) steps.clone();
|
||||||
Step step1 = opSteps.removeFirst();
|
Step step1 = opSteps.removeFirst();
|
||||||
Mono<List<StepResponse>> result = runStep(step1, null).expand(response -> {
|
Mono<List<StepResponse>> result = runStep(step1, null).expand(lastStepResponse -> {
|
||||||
if (opSteps.isEmpty() || response.isStop()) {
|
if (opSteps.isEmpty() || lastStepResponse.isStop()) {
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
Step step = opSteps.pop();
|
Step step = opSteps.pop();
|
||||||
return runStep(step, response);
|
return runStep(step, lastStepResponse);
|
||||||
}).flatMap(response -> Flux.just(response)).collectList();
|
}).flatMap(response -> Flux.just(response)).collectList();
|
||||||
return result.flatMap(clientResponse -> {
|
return result.flatMap(clientResponse -> {
|
||||||
return handleOutput(input);
|
return handleOutput(input);
|
||||||
@@ -132,7 +132,9 @@ public class Pipeline {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Mono<StepResponse> runStep(Step step, StepResponse response){
|
private Mono<StepResponse> runStep(Step step, StepResponse lastStepResponse){
|
||||||
|
StepResponse stepResponse = new StepResponse(step, null, new HashMap<String, Map<String, Object>>());
|
||||||
|
stepContext.put(step.getName(), stepResponse);
|
||||||
List<IComponent> components = step.getComponents();
|
List<IComponent> components = step.getComponents();
|
||||||
if (components != null && components.size() > 0) {
|
if (components != null && components.size() > 0) {
|
||||||
StepContextPosition stepCtxPos = new StepContextPosition(step.getName());
|
StepContextPosition stepCtxPos = new StepContextPosition(step.getName());
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ public class Step {
|
|||||||
public void beforeRun(StepContext<String, Object> stepContext2, StepResponse response ) {
|
public void beforeRun(StepContext<String, Object> stepContext2, StepResponse response ) {
|
||||||
stepContext = stepContext2;
|
stepContext = stepContext2;
|
||||||
lastStepResponse = response;
|
lastStepResponse = response;
|
||||||
StepResponse stepResponse = new StepResponse(this, null, new HashMap<String, Map<String, Object>>());
|
StepResponse stepResponse = (StepResponse) stepContext.get(this.name);
|
||||||
stepContext.put(name, stepResponse);
|
|
||||||
Map<String, InputConfig> configs = this.getRequestConfigs();
|
Map<String, InputConfig> configs = this.getRequestConfigs();
|
||||||
for(String configName :configs.keySet()) {
|
for(String configName :configs.keySet()) {
|
||||||
InputConfig inputConfig = configs.get(configName);
|
InputConfig inputConfig = configs.get(configName);
|
||||||
|
|||||||
@@ -801,6 +801,48 @@ public class StepContext<K, V> extends ConcurrentHashMap<K, V> {
|
|||||||
circle.add(circleResult);
|
circle.add(circleResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置判断条件组件结果<br>
|
||||||
|
* Set result of condition components <br>
|
||||||
|
*
|
||||||
|
* @param stepName step name
|
||||||
|
* @param requestName request name
|
||||||
|
* @param conditionDesc condition description, such as: <br>
|
||||||
|
* circle[0]-execCondition:my condition 1<br>
|
||||||
|
* circle[1]-breakCondition:my condition 2<br>
|
||||||
|
* condition:my condition 3<br>
|
||||||
|
* @param rs result of condition component
|
||||||
|
*/
|
||||||
|
public void addConditionResult(String stepName, String requestName, String conditionDesc, boolean rs) {
|
||||||
|
if (requestName == null) {
|
||||||
|
StepResponse stepResponse = (StepResponse) this.get(stepName);
|
||||||
|
if (stepResponse == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> results = (List<Map<String, Object>>) stepResponse.getConditionResults();
|
||||||
|
if (results == null) {
|
||||||
|
results = new ArrayList<>();
|
||||||
|
stepResponse.setConditionResults(results);
|
||||||
|
}
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put(conditionDesc, rs);
|
||||||
|
results.add(result);
|
||||||
|
} else {
|
||||||
|
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||||
|
if (request == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<Map<String, Object>> results = (List<Map<String, Object>>) request.get("conditionResults");
|
||||||
|
if (results == null) {
|
||||||
|
results = new ArrayList<>();
|
||||||
|
request.put("conditionResults", results);
|
||||||
|
}
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put(conditionDesc, rs);
|
||||||
|
results.add(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取请求的循环对象<br>
|
* 获取请求的循环对象<br>
|
||||||
* Returns the current circle item of request<br>
|
* Returns the current circle item of request<br>
|
||||||
@@ -808,12 +850,12 @@ public class StepContext<K, V> extends ConcurrentHashMap<K, V> {
|
|||||||
* @param stepName
|
* @param stepName
|
||||||
* @param requestName
|
* @param requestName
|
||||||
*/
|
*/
|
||||||
public List<Map<String, Object>> getRequestCircleItem(String stepName, String requestName) {
|
public Object getRequestCircleItem(String stepName, String requestName) {
|
||||||
Map<String, Object> request = getStepRequest(stepName, requestName);
|
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (List<Map<String, Object>>) request.get("circle");
|
return request.get("item");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -823,12 +865,12 @@ public class StepContext<K, V> extends ConcurrentHashMap<K, V> {
|
|||||||
* @param stepName
|
* @param stepName
|
||||||
* @param requestName
|
* @param requestName
|
||||||
*/
|
*/
|
||||||
public Object getRequestCircle(String stepName, String requestName) {
|
public List<Map<String, Object>> getRequestCircle(String stepName, String requestName) {
|
||||||
Map<String, Object> request = getStepRequest(stepName, requestName);
|
Map<String, Object> request = getStepRequest(stepName, requestName);
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return request.get("item");
|
return (List<Map<String, Object>>) request.get("circle");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object deepCopy(Object obj) {
|
private Object deepCopy(Object obj) {
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public class StepResponse {
|
|||||||
private Integer index;
|
private Integer index;
|
||||||
// circle results
|
// circle results
|
||||||
private List<Map<String,Object>> circle;
|
private List<Map<String,Object>> circle;
|
||||||
|
// result of condition components
|
||||||
|
private List<Map<String,Object>> conditionResults;
|
||||||
|
|
||||||
public StepResponse(Step aStep, HashMap item, Map<String, Map<String, Object>> requests) {
|
public StepResponse(Step aStep, HashMap item, Map<String, Map<String, Object>> requests) {
|
||||||
setStepName(aStep.getName());
|
setStepName(aStep.getName());
|
||||||
@@ -96,5 +98,11 @@ public class StepResponse {
|
|||||||
public void setIndex(Integer index) {
|
public void setIndex(Integer index) {
|
||||||
this.index = index;
|
this.index = index;
|
||||||
}
|
}
|
||||||
|
public List<Map<String, Object>> getConditionResults() {
|
||||||
|
return conditionResults;
|
||||||
|
}
|
||||||
|
public void setConditionResults(List<Map<String, Object>> conditionResults) {
|
||||||
|
this.conditionResults = conditionResults;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,60 +98,20 @@ public class ComponentHelper {
|
|||||||
if (conditions != null && conditions.size() > 0) {
|
if (conditions != null && conditions.size() > 0) {
|
||||||
ONode ctxNode = toONode(stepContext);
|
ONode ctxNode = toONode(stepContext);
|
||||||
for (Condition c : conditions) {
|
for (Condition c : conditions) {
|
||||||
if (!c.exec(ctxNode)) {
|
boolean rs = c.exec(ctxNode);
|
||||||
return null;
|
stepContext.addConditionResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName(), c.getDesc(),
|
||||||
|
rs);
|
||||||
|
if (!rs) {
|
||||||
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (circle != null) {
|
if (circle != null) {
|
||||||
return circle.exec(stepContext, stepCtxPos, f);
|
return circle.exec(stepContext, stepCtxPos, f);
|
||||||
|
} else {
|
||||||
|
return f.apply(stepContext, stepCtxPos);
|
||||||
}
|
}
|
||||||
// // conditions before circle component
|
|
||||||
// List<Condition> conditions1 = new ArrayList<>();
|
|
||||||
// // conditions after circle component
|
|
||||||
// List<Condition> conditions2 = new ArrayList<>();
|
|
||||||
// Circle circle = null;
|
|
||||||
// for (IComponent component : components) {
|
|
||||||
// if (ComponentTypeEnum.CIRCLE == component.getType()) {
|
|
||||||
// circle = (Circle) component;
|
|
||||||
// }
|
|
||||||
// if (circle == null && ComponentTypeEnum.CONDITION == component.getType()) {
|
|
||||||
// conditions1.add((Condition) component);
|
|
||||||
// }
|
|
||||||
// if (circle != null && ComponentTypeEnum.CONDITION == component.getType()) {
|
|
||||||
// conditions2.add((Condition) component);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (conditions1 != null && conditions1.size() > 0) {
|
|
||||||
// ONode ctxNode = toONode(stepContext);
|
|
||||||
// for (Condition c : conditions1) {
|
|
||||||
// if (!c.exec(ctxNode)) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (circle != null) {
|
|
||||||
// return circle.exec(stepContext, (ctx) -> {
|
|
||||||
// boolean canRun = true;
|
|
||||||
// if (conditions2 != null && conditions2.size() > 0) {
|
|
||||||
// ONode ctxNode = toONode(ctx);
|
|
||||||
// for (Condition c : conditions2) {
|
|
||||||
// if (!c.exec(ctxNode)) {
|
|
||||||
// canRun = false;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (canRun) {
|
|
||||||
// return f.apply(ctx);
|
|
||||||
// } else {
|
|
||||||
// return Mono.empty();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,8 @@ import java.util.Collection;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.noear.snack.ONode;
|
import org.noear.snack.ONode;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import reactor.core.publisher.Flux;
|
import reactor.core.publisher.Flux;
|
||||||
@@ -39,7 +36,6 @@ import we.fizz.component.ValueTypeEnum;
|
|||||||
import we.fizz.component.condition.Condition;
|
import we.fizz.component.condition.Condition;
|
||||||
import we.fizz.exception.FizzRuntimeException;
|
import we.fizz.exception.FizzRuntimeException;
|
||||||
import we.fizz.input.PathMapping;
|
import we.fizz.input.PathMapping;
|
||||||
import we.fizz.input.RPCInput;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Circle component
|
* Circle component
|
||||||
@@ -102,7 +98,7 @@ public class Circle implements IComponent {
|
|||||||
/**
|
/**
|
||||||
* Reference value of dataSource
|
* Reference value of dataSource
|
||||||
*/
|
*/
|
||||||
private List<Object> refValue;
|
private Object refValue;
|
||||||
|
|
||||||
private boolean refReadFlag;
|
private boolean refReadFlag;
|
||||||
|
|
||||||
@@ -113,8 +109,12 @@ public class Circle implements IComponent {
|
|||||||
if (dataSource == null) {
|
if (dataSource == null) {
|
||||||
return fixedValue;
|
return fixedValue;
|
||||||
}
|
}
|
||||||
if (dataSource instanceof Integer || dataSource instanceof Long) {
|
if (dataSource instanceof Integer || dataSource instanceof Long || dataSource instanceof String) {
|
||||||
fixedValue = Integer.valueOf(dataSource.toString());
|
try {
|
||||||
|
fixedValue = Integer.valueOf(dataSource.toString());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer");
|
||||||
|
}
|
||||||
if (fixedValue.intValue() < 1) {
|
if (fixedValue.intValue() < 1) {
|
||||||
throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer");
|
throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer");
|
||||||
}
|
}
|
||||||
@@ -125,7 +125,7 @@ public class Circle implements IComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private List<Object> getRefValue(ONode ctxNode) {
|
private Object getRefValue(ONode ctxNode) {
|
||||||
if (refReadFlag) {
|
if (refReadFlag) {
|
||||||
return refValue;
|
return refValue;
|
||||||
}
|
}
|
||||||
@@ -136,8 +136,24 @@ public class Circle implements IComponent {
|
|||||||
if (value instanceof Collection) {
|
if (value instanceof Collection) {
|
||||||
refValue = (List<Object>) value;
|
refValue = (List<Object>) value;
|
||||||
return refValue;
|
return refValue;
|
||||||
|
} else if (value instanceof Integer || value instanceof Long || value instanceof String) {
|
||||||
|
try {
|
||||||
|
Integer times = Integer.valueOf(value.toString());
|
||||||
|
if (times.intValue() < 1) {
|
||||||
|
throw new FizzRuntimeException(
|
||||||
|
"invalid data source, data source must be a positive integer or an array");
|
||||||
|
}
|
||||||
|
refValue = times;
|
||||||
|
} catch (FizzRuntimeException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new FizzRuntimeException(
|
||||||
|
"invalid data source, data source must be a positive integer or an array");
|
||||||
|
}
|
||||||
|
return refValue;
|
||||||
} else {
|
} else {
|
||||||
throw new FizzRuntimeException("invalid data source, referenced data source must be a array");
|
throw new FizzRuntimeException(
|
||||||
|
"invalid data source, referenced data source must be a positive integer or an array");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,32 +162,49 @@ public class Circle implements IComponent {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public CircleItem next(ONode ctxNode) {
|
public CircleItem next(ONode ctxNode) {
|
||||||
if (ValueTypeEnum.FIXED.equals(dataSourceType)) {
|
if (ValueTypeEnum.FIXED.equals(dataSourceType)) {
|
||||||
Integer total = this.getFixedValue(ctxNode);
|
Integer total = this.getFixedValue(ctxNode);
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
index = 0;
|
index = 0;
|
||||||
currentItem = index;
|
currentItem = index + 1;
|
||||||
return new CircleItem(currentItem, index);
|
return new CircleItem(currentItem, index);
|
||||||
} else if (index.intValue() < total.intValue() - 1) {
|
} else if (index.intValue() < total.intValue() - 1) {
|
||||||
index = index + 1;
|
index = index + 1;
|
||||||
currentItem = index;
|
currentItem = index + 1;
|
||||||
return new CircleItem(currentItem, index);
|
return new CircleItem(currentItem, index);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} else if (ValueTypeEnum.REF.equals(dataSourceType)) {
|
} else if (ValueTypeEnum.REF.equals(dataSourceType)) {
|
||||||
List<Object> list = this.getRefValue(ctxNode);
|
Object refValue = this.getRefValue(ctxNode);
|
||||||
if (index == null) {
|
if (refValue instanceof Collection) {
|
||||||
index = 0;
|
List<Object> list = (List<Object>) refValue;
|
||||||
currentItem = list.get(index);
|
if (index == null) {
|
||||||
return new CircleItem(currentItem, index);
|
index = 0;
|
||||||
} else if (index.intValue() < list.size() - 1) {
|
currentItem = list.get(index);
|
||||||
index = index + 1;
|
return new CircleItem(currentItem, index);
|
||||||
currentItem = list.get(index);
|
} else if (index.intValue() < list.size() - 1) {
|
||||||
return new CircleItem(currentItem, index);
|
index = index + 1;
|
||||||
} else {
|
currentItem = list.get(index);
|
||||||
return null;
|
return new CircleItem(currentItem, index);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else if (refValue instanceof Integer) {
|
||||||
|
Integer total = (Integer) refValue;
|
||||||
|
if (index == null) {
|
||||||
|
index = 0;
|
||||||
|
currentItem = index + 1;
|
||||||
|
return new CircleItem(currentItem, index);
|
||||||
|
} else if (index.intValue() < total.intValue() - 1) {
|
||||||
|
index = index + 1;
|
||||||
|
currentItem = index + 1;
|
||||||
|
return new CircleItem(currentItem, index);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@@ -183,11 +216,15 @@ public class Circle implements IComponent {
|
|||||||
* @param ctxNode
|
* @param ctxNode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean canExec(ONode ctxNode) {
|
public boolean canExec(int index, ONode ctxNode, StepContext<String, Object> stepContext,
|
||||||
|
StepContextPosition stepCtxPos) {
|
||||||
if (this.execConditions != null && this.execConditions.size() > 0) {
|
if (this.execConditions != null && this.execConditions.size() > 0) {
|
||||||
try {
|
try {
|
||||||
for (Condition condition : execConditions) {
|
for (Condition c : execConditions) {
|
||||||
if (!condition.exec(ctxNode)) {
|
boolean rs = c.exec(ctxNode);
|
||||||
|
stepContext.addConditionResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName(),
|
||||||
|
"circle[" + index + "]-execCondition:" + c.getDesc(), rs);
|
||||||
|
if (!rs) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,11 +241,15 @@ public class Circle implements IComponent {
|
|||||||
* @param ctxNode
|
* @param ctxNode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public boolean breakCircle(ONode ctxNode) {
|
public boolean breakCircle(int index, ONode ctxNode, StepContext<String, Object> stepContext,
|
||||||
|
StepContextPosition stepCtxPos) {
|
||||||
if (this.breakConditions != null && this.breakConditions.size() > 0) {
|
if (this.breakConditions != null && this.breakConditions.size() > 0) {
|
||||||
try {
|
try {
|
||||||
for (Condition condition : breakConditions) {
|
for (Condition c : breakConditions) {
|
||||||
if (condition.exec(ctxNode)) {
|
boolean rs = c.exec(ctxNode);
|
||||||
|
stepContext.addConditionResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName(),
|
||||||
|
"circle[" + index + "]-breakCondition:" + c.getDesc(), rs);
|
||||||
|
if (rs) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,14 +260,14 @@ public class Circle implements IComponent {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||||
public Mono<Object> exec(StepContext<String, Object> stepContext, StepContextPosition stepCtxPos,
|
public Mono<Object> exec(StepContext<String, Object> stepContext, StepContextPosition stepCtxPos,
|
||||||
BiFunction<StepContext, StepContextPosition, Mono> f) {
|
BiFunction<StepContext, StepContextPosition, Mono> f) {
|
||||||
ONode ctxNode = ComponentHelper.toONode(stepContext);
|
ONode ctxNode1 = ComponentHelper.toONode(stepContext);
|
||||||
CircleItem nextItem = this.next(ctxNode);
|
CircleItem nextItem = this.next(ctxNode1);
|
||||||
if (nextItem != null) {
|
if (nextItem != null) {
|
||||||
return Mono.just(new CircleItemResult(nextItem, null)).expand(circleItemResult -> {
|
return Mono.just(new CircleItemResult(ctxNode1, nextItem, null)).expand(circleItemResult -> {
|
||||||
// put nextItem to step context and ctxNode for further JSON path mapping
|
// put nextItem to step context
|
||||||
CircleItem cItem = circleItemResult.nextItem;
|
CircleItem cItem = circleItemResult.nextItem;
|
||||||
if (stepCtxPos.getRequestName() != null) {
|
if (stepCtxPos.getRequestName() != null) {
|
||||||
stepContext.setRequestCircleItem(stepCtxPos.getStepName(), stepCtxPos.getRequestName(),
|
stepContext.setRequestCircleItem(stepCtxPos.getStepName(), stepCtxPos.getRequestName(),
|
||||||
@@ -234,23 +275,26 @@ public class Circle implements IComponent {
|
|||||||
} else {
|
} else {
|
||||||
stepContext.setStepCircleItem(stepCtxPos.getStepName(), cItem.getItem(), cItem.getIndex());
|
stepContext.setStepCircleItem(stepCtxPos.getStepName(), cItem.getItem(), cItem.getIndex());
|
||||||
}
|
}
|
||||||
|
ONode ctxNode = circleItemResult.ctxNode;
|
||||||
PathMapping.setByPath(ctxNode, stepCtxPos.getPath() + ".item", cItem.getItem(), true);
|
PathMapping.setByPath(ctxNode, stepCtxPos.getPath() + ".item", cItem.getItem(), true);
|
||||||
PathMapping.setByPath(ctxNode, stepCtxPos.getPath() + ".index", cItem.getIndex(), true);
|
PathMapping.setByPath(ctxNode, stepCtxPos.getPath() + ".index", cItem.getIndex(), true);
|
||||||
|
|
||||||
if (!this.canExec(ctxNode)) {
|
if (!this.canExec(cItem.getIndex(), ctxNode, stepContext, stepCtxPos)) {
|
||||||
return Mono.just(new CircleItemResult(this.next(ctxNode), null));
|
return Mono.just(new CircleItemResult(ctxNode, this.next(ctxNode), null));
|
||||||
}
|
|
||||||
if (this.breakCircle(ctxNode)) {
|
|
||||||
return Mono.empty();
|
|
||||||
}
|
}
|
||||||
return f.apply(stepContext, stepCtxPos).flatMap(r -> {
|
return f.apply(stepContext, stepCtxPos).flatMap(r -> {
|
||||||
CircleItem nextItem2 = this.next(ctxNode);
|
ONode ctxNode2 = ComponentHelper.toONode(stepContext);
|
||||||
|
if (this.breakCircle(cItem.getIndex(), ctxNode, stepContext, stepCtxPos)) {
|
||||||
|
return Mono.empty();
|
||||||
|
}
|
||||||
|
CircleItem nextItem2 = this.next(ctxNode2);
|
||||||
if (nextItem2 == null) {
|
if (nextItem2 == null) {
|
||||||
return Mono.empty();
|
return Mono.empty();
|
||||||
}
|
}
|
||||||
return Mono.just(new CircleItemResult(nextItem2, r));
|
return Mono.just(new CircleItemResult(ctxNode2, nextItem2, r));
|
||||||
});
|
});
|
||||||
}).flatMap(circleItemResult -> Flux.just(circleItemResult)).collectList().flatMap(list -> {
|
}).flatMap(circleItemResult -> Flux.just(circleItemResult)).collectList().flatMap(r -> {
|
||||||
|
List<CircleItemResult> list = (List<CircleItemResult>) r;
|
||||||
if (list != null && list.size() > 0) {
|
if (list != null && list.size() > 0) {
|
||||||
Collections.reverse(list);
|
Collections.reverse(list);
|
||||||
for (int i = 0; i < list.size(); i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
@@ -268,10 +312,12 @@ public class Circle implements IComponent {
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
class CircleItemResult {
|
class CircleItemResult {
|
||||||
|
private ONode ctxNode;
|
||||||
private CircleItem nextItem;
|
private CircleItem nextItem;
|
||||||
private Object result;
|
private Object result;
|
||||||
|
|
||||||
public CircleItemResult(CircleItem nextItem, Object result) {
|
public CircleItemResult(ONode ctxNode, CircleItem nextItem, Object result) {
|
||||||
|
this.ctxNode = ctxNode;
|
||||||
this.nextItem = nextItem;
|
this.nextItem = nextItem;
|
||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ public class Condition implements IComponent {
|
|||||||
case CONTAINS:
|
case CONTAINS:
|
||||||
if (v1 == null) {
|
if (v1 == null) {
|
||||||
rs = false;
|
rs = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (v1 instanceof Collection && !(v2 instanceof Collection)) {
|
if (v1 instanceof Collection && !(v2 instanceof Collection)) {
|
||||||
Collection coll1 = (Collection) v1;
|
Collection coll1 = (Collection) v1;
|
||||||
@@ -143,6 +144,7 @@ public class Condition implements IComponent {
|
|||||||
case NOT_CONTAIN:
|
case NOT_CONTAIN:
|
||||||
if (v1 == null) {
|
if (v1 == null) {
|
||||||
rs = true;
|
rs = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (v1 instanceof Collection && !(v2 instanceof Collection)) {
|
if (v1 instanceof Collection && !(v2 instanceof Collection)) {
|
||||||
Collection coll1 = (Collection) v1;
|
Collection coll1 = (Collection) v1;
|
||||||
@@ -162,6 +164,7 @@ public class Condition implements IComponent {
|
|||||||
case CONTAINS_ANY:
|
case CONTAINS_ANY:
|
||||||
if (v1 == null || v2 == null) {
|
if (v1 == null || v2 == null) {
|
||||||
rs = false;
|
rs = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (v1 instanceof Collection && v2 instanceof Collection) {
|
if (v1 instanceof Collection && v2 instanceof Collection) {
|
||||||
Collection coll1 = (Collection) v1;
|
Collection coll1 = (Collection) v1;
|
||||||
@@ -235,7 +238,7 @@ public class Condition implements IComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Object cast(RefDataTypeEnum type, Object val) {
|
private Object cast(RefDataTypeEnum type, Object val) {
|
||||||
if (type != null) {
|
if (type != null && val != null) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case INT:
|
case INT:
|
||||||
val = Integer.valueOf(val.toString());
|
val = Integer.valueOf(val.toString());
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.List;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.noear.snack.ONode;
|
import org.noear.snack.ONode;
|
||||||
|
|
||||||
|
import we.fizz.StepContext;
|
||||||
import we.fizz.component.circle.Circle;
|
import we.fizz.component.circle.Circle;
|
||||||
import we.fizz.component.circle.CircleItem;
|
import we.fizz.component.circle.CircleItem;
|
||||||
import we.fizz.component.condition.Condition;
|
import we.fizz.component.condition.Condition;
|
||||||
@@ -41,7 +42,6 @@ class CircleTests {
|
|||||||
void contextLoads() {
|
void contextLoads() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("rawtypes")
|
@SuppressWarnings("rawtypes")
|
||||||
@Test
|
@Test
|
||||||
void testNextFixedDataSource() {
|
void testNextFixedDataSource() {
|
||||||
@@ -50,14 +50,14 @@ class CircleTests {
|
|||||||
// FIXED data source
|
// FIXED data source
|
||||||
Circle c = new Circle(null, ValueTypeEnum.FIXED, 3, null, null);
|
Circle c = new Circle(null, ValueTypeEnum.FIXED, 3, null, null);
|
||||||
CircleItem circleItem = c.next(ctxNode);
|
CircleItem circleItem = c.next(ctxNode);
|
||||||
assertEquals(0, (Integer) circleItem.getItem());
|
|
||||||
|
|
||||||
circleItem = c.next(ctxNode);
|
|
||||||
assertEquals(1, (Integer) circleItem.getItem());
|
assertEquals(1, (Integer) circleItem.getItem());
|
||||||
|
|
||||||
circleItem = c.next(ctxNode);
|
circleItem = c.next(ctxNode);
|
||||||
assertEquals(2, (Integer) circleItem.getItem());
|
assertEquals(2, (Integer) circleItem.getItem());
|
||||||
|
|
||||||
|
circleItem = c.next(ctxNode);
|
||||||
|
assertEquals(3, (Integer) circleItem.getItem());
|
||||||
|
|
||||||
circleItem = c.next(ctxNode);
|
circleItem = c.next(ctxNode);
|
||||||
assertEquals(null, circleItem);
|
assertEquals(null, circleItem);
|
||||||
|
|
||||||
@@ -115,7 +115,8 @@ class CircleTests {
|
|||||||
CircleItem circleItem = circle.next(ctxNode);
|
CircleItem circleItem = circle.next(ctxNode);
|
||||||
PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true);
|
PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true);
|
||||||
PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true);
|
PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true);
|
||||||
boolean rs = circle.canExec(ctxNode);
|
boolean rs = circle.canExec(circleItem.getIndex(), ctxNode, new StepContext<String, Object>(),
|
||||||
|
new StepContextPosition("step1", null));
|
||||||
assertEquals(i, circleItem.getIndex());
|
assertEquals(i, circleItem.getIndex());
|
||||||
if (i < 3) {
|
if (i < 3) {
|
||||||
assertEquals(true, rs);
|
assertEquals(true, rs);
|
||||||
@@ -127,7 +128,7 @@ class CircleTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBreakCondition() {
|
void testBreakCondition() {
|
||||||
ONode ctxNode = ONode.load(new HashMap());
|
ONode ctxNode = ONode.load(new HashMap());
|
||||||
@@ -154,7 +155,9 @@ class CircleTests {
|
|||||||
CircleItem circleItem = circle.next(ctxNode);
|
CircleItem circleItem = circle.next(ctxNode);
|
||||||
PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true);
|
PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true);
|
||||||
PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true);
|
PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true);
|
||||||
boolean rs = circle.breakCircle(ctxNode);
|
|
||||||
|
boolean rs = circle.breakCircle(circleItem.getIndex(), ctxNode, new StepContext<String, Object>(),
|
||||||
|
new StepContextPosition("step1", null));
|
||||||
assertEquals(i, circleItem.getIndex());
|
assertEquals(i, circleItem.getIndex());
|
||||||
if (i < 3) {
|
if (i < 3) {
|
||||||
assertEquals(false, rs);
|
assertEquals(false, rs);
|
||||||
|
|||||||
Reference in New Issue
Block a user