diff --git a/fizz-core/pom.xml b/fizz-core/pom.xml index 8d3960a..53935a1 100644 --- a/fizz-core/pom.xml +++ b/fizz-core/pom.xml @@ -13,9 +13,16 @@ fizz-core + 1.0.0-SNAPSHOT + + com.fizzgate + fizz-aggregate-spring-boot-starter + ${aggregate.version} + + com.lmax disruptor diff --git a/fizz-core/src/main/java/com/fizzgate/config/AppConfigProperties.java b/fizz-core/src/main/java/com/fizzgate/config/AppConfigProperties.java deleted file mode 100644 index 6e4fa5a..0000000 --- a/fizz-core/src/main/java/com/fizzgate/config/AppConfigProperties.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.config; - -import lombok.Data; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.stereotype.Component; - -@RefreshScope -@Component -@Data -public class AppConfigProperties { - - @Value("${spring.profiles.active}") - private String env; -} - diff --git a/fizz-core/src/main/java/com/fizzgate/config/RefreshLocalCacheConfig.java b/fizz-core/src/main/java/com/fizzgate/config/RefreshLocalCacheConfig.java index 3148837..355a7b1 100644 --- a/fizz-core/src/main/java/com/fizzgate/config/RefreshLocalCacheConfig.java +++ b/fizz-core/src/main/java/com/fizzgate/config/RefreshLocalCacheConfig.java @@ -16,12 +16,12 @@ */ package com.fizzgate.config; +import com.fizzgate.aggregate.web.loader.ConfigLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.annotation.Scheduled; -import com.fizzgate.fizz.ConfigLoader; import com.fizzgate.plugin.auth.ApiConfig2appsService; import com.fizzgate.plugin.auth.ApiConfigService; import com.fizzgate.plugin.auth.AppService; diff --git a/fizz-core/src/main/java/com/fizzgate/controller/ConfigController.java b/fizz-core/src/main/java/com/fizzgate/controller/ConfigController.java index 807e2e1..e97539c 100644 --- a/fizz-core/src/main/java/com/fizzgate/controller/ConfigController.java +++ b/fizz-core/src/main/java/com/fizzgate/controller/ConfigController.java @@ -17,12 +17,12 @@ package com.fizzgate.controller; +import com.fizzgate.aggregate.web.loader.ConfigLoader; import org.apache.commons.io.FileUtils; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.server.ServerWebExchange; -import com.fizzgate.fizz.ConfigLoader; import com.fizzgate.util.ScriptUtils; import reactor.core.publisher.Mono; diff --git a/fizz-core/src/main/java/com/fizzgate/controller/ManagerConfigController.java b/fizz-core/src/main/java/com/fizzgate/controller/ManagerConfigController.java index 263dbff..92e683c 100644 --- a/fizz-core/src/main/java/com/fizzgate/controller/ManagerConfigController.java +++ b/fizz-core/src/main/java/com/fizzgate/controller/ManagerConfigController.java @@ -17,6 +17,7 @@ package com.fizzgate.controller; +import com.fizzgate.aggregate.web.loader.ConfigLoader; import com.fizzgate.controller.req.BaseManagerConfigReq; import com.fizzgate.controller.req.GetApiConfigDetailReq; import com.fizzgate.controller.req.GetApiConfigReq; @@ -27,7 +28,6 @@ import com.fizzgate.controller.resp.ConfigResp; import com.fizzgate.controller.resp.ConfigStrResp; import com.fizzgate.controller.resp.GetApiConfigDetailResp; import com.fizzgate.controller.resp.GetApiConfigResp; -import com.fizzgate.fizz.ConfigLoader; import com.fizzgate.plugin.PluginConfig; import com.fizzgate.plugin.auth.ApiConfig; import com.fizzgate.plugin.auth.ApiConfig2appsService; diff --git a/fizz-core/src/main/java/com/fizzgate/controller/resp/ConfigResp.java b/fizz-core/src/main/java/com/fizzgate/controller/resp/ConfigResp.java index c69ed7d..9e55f8c 100644 --- a/fizz-core/src/main/java/com/fizzgate/controller/resp/ConfigResp.java +++ b/fizz-core/src/main/java/com/fizzgate/controller/resp/ConfigResp.java @@ -17,12 +17,12 @@ package com.fizzgate.controller.resp; +import com.fizzgate.aggregate.web.loader.ConfigLoader; + import java.io.Serializable; import java.util.List; import java.util.Objects; -import com.fizzgate.fizz.ConfigLoader; - /** * 聚合配置响应实体类 * @author zhongjie diff --git a/fizz-core/src/main/java/com/fizzgate/exception/ExecuteScriptException.java b/fizz-core/src/main/java/com/fizzgate/exception/ExecuteScriptException.java deleted file mode 100644 index ffd88f8..0000000 --- a/fizz-core/src/main/java/com/fizzgate/exception/ExecuteScriptException.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.exception; - -import com.fizzgate.fizz.StepContext; - -/** - * @author Francis - */ -public class ExecuteScriptException extends RuntimeException { - - private StepContext stepContext; - - private Object data; - - public ExecuteScriptException(String message, StepContext stepContext, Object data) { - super(message); - this.data = data; - this.stepContext = stepContext; - this.stepContext.setExceptionInfo(this, data); - } - - public ExecuteScriptException(Throwable cause, StepContext stepContext, Object data) { - super("execute script failed: " + cause.getMessage(), cause); - this.data = data; - this.stepContext = stepContext; - this.setStackTrace(cause.getStackTrace()); - this.stepContext.setExceptionInfo(this, data); - } - - /** - * - */ - private static final long serialVersionUID = 1L; - - public Object getData() { - return data; - } - - public void setData(Object data) { - this.data = data; - } - - public StepContext getStepContext() { - return stepContext; - } - - public void setStepContext(StepContext stepContext) { - this.stepContext = stepContext; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/exception/RedirectException.java b/fizz-core/src/main/java/com/fizzgate/exception/RedirectException.java deleted file mode 100644 index 27a2f65..0000000 --- a/fizz-core/src/main/java/com/fizzgate/exception/RedirectException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.exception; - -/** - * @author Francis - */ -public class RedirectException extends RuntimeException { - - private String redirectUrl; - - public RedirectException(String message, String redirectUrl) { - super(message); - this.redirectUrl = redirectUrl; - } - - /** - * - */ - private static final long serialVersionUID = 1L; - - public String getRedirectUrl() { - return redirectUrl; - } - - public void setRedirectUrl(String redirectUrl) { - this.redirectUrl = redirectUrl; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/exception/StopAndResponseException.java b/fizz-core/src/main/java/com/fizzgate/exception/StopAndResponseException.java deleted file mode 100644 index 2ff078f..0000000 --- a/fizz-core/src/main/java/com/fizzgate/exception/StopAndResponseException.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.exception; - -/** - * @author Francis - */ -public class StopAndResponseException extends RuntimeException { - - private String data; - - public StopAndResponseException(String message, String data) { - super(message); - this.data = data; - } - - /** - * - */ - private static final long serialVersionUID = 1L; - - public String getData() { - return data; - } - - public void setData(String data) { - this.data = data; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/filter/AggregateFilter.java b/fizz-core/src/main/java/com/fizzgate/filter/AggregateFilter.java deleted file mode 100644 index 96a73fc..0000000 --- a/fizz-core/src/main/java/com/fizzgate/filter/AggregateFilter.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.filter; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializerFeature; -import com.fizzgate.config.SystemConfig; -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.fizz.AggregateResource; -import com.fizzgate.fizz.AggregateResult; -import com.fizzgate.fizz.ConfigLoader; -import com.fizzgate.fizz.Pipeline; -import com.fizzgate.fizz.input.Input; -import com.fizzgate.plugin.auth.ApiConfig; -import com.fizzgate.util.Consts; -import com.fizzgate.util.MapUtil; -import com.fizzgate.util.NettyDataBufferUtils; -import com.fizzgate.util.WebUtils; - -import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.ThreadContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.annotation.Order; -import org.springframework.core.io.buffer.DataBufferUtils; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.codec.multipart.FilePart; -import org.springframework.http.server.reactive.ServerHttpRequest; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.stereotype.Component; -import org.springframework.web.server.ServerWebExchange; -import org.springframework.web.server.WebFilter; -import org.springframework.web.server.WebFilterChain; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; - -import javax.annotation.Resource; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -/** - * @author Francis Dong - */ -@Component -@Order(30) -public class AggregateFilter implements WebFilter { - - private static final Logger LOGGER = LoggerFactory.getLogger(AggregateFilter.class); - - private static final String X_FORWARDED_FOR = "X-FORWARDED-FOR"; - - @Resource - private ConfigLoader configLoader; - - @Resource - private AggregateFilterProperties aggregateFilterProperties; - - @Resource - private SystemConfig systemConfig; - - @Override - public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { - - String serviceId = WebUtils.getBackendService(exchange); - if (serviceId == null) { - return chain.filter(exchange); - } else if (WebUtils.ignorePlugin(exchange) && WebUtils.getRoute(exchange).type == ApiConfig.Type.SERVICE_AGGREGATE) { - } else { - byte act = WebUtils.getApiConfigType(exchange); - if (act == ApiConfig.Type.UNDEFINED) { - String p = exchange.getRequest().getURI().getPath(); - if (StringUtils.startsWith(p, SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX0)) { - if (systemConfig.isAggregateTestAuth()) { - return chain.filter(exchange); - } - } else if (aggregateFilterProperties.isNeedAuth()) { - return chain.filter(exchange); - } - } else if (act != ApiConfig.Type.SERVICE_AGGREGATE) { - return chain.filter(exchange); - } - } - - FilterResult pfr = WebUtils.getPrevFilterResult(exchange); - if (!pfr.success) { - return WebUtils.getDirectResponse(exchange); - } - - long start = System.currentTimeMillis(); - ServerHttpRequest request = exchange.getRequest(); - ServerHttpResponse serverHttpResponse = exchange.getResponse(); - - String clientReqPathPrefix = WebUtils.getClientReqPathPrefix(exchange); - String path = clientReqPathPrefix + serviceId + WebUtils.getBackendPath(exchange); - String method = request.getMethodValue(); - if (HttpMethod.HEAD.matches(method.toUpperCase())) { - method = HttpMethod.GET.name(); - } - AggregateResource aggregateResource = configLoader.matchAggregateResource(method, path); - if (aggregateResource == null) { - if (SystemConfig.DEFAULT_GATEWAY_TEST_PREFIX0.equals(clientReqPathPrefix) || - WebUtils.getApiConfigType(exchange) == ApiConfig.Type.SERVICE_AGGREGATE) { - return WebUtils.responseError(exchange, HttpStatus.NOT_FOUND.value(), "API not found in aggregation: " + path); - } else { - return chain.filter(exchange); - } - } - - Pipeline pipeline = aggregateResource.getPipeline(); - Input input = aggregateResource.getInput(); - - HttpHeaders hds = request.getHeaders(); - Map headers = MapUtil.headerToHashMap(hds); - if (CollectionUtils.isEmpty(hds.get(X_FORWARDED_FOR)) && systemConfig.isFizzWebClientXForwardedForEnable()) { - headers.put(X_FORWARDED_FOR, WebUtils.getOriginIp(exchange)); - } - Map fizzHeaders = (Map) exchange.getAttributes().get(WebUtils.APPEND_HEADERS); - if (fizzHeaders != null && !fizzHeaders.isEmpty()) { - Set> entrys = fizzHeaders.entrySet(); - for (Entry entry : entrys) { - headers.put(entry.getKey().toUpperCase(), entry.getValue()); - } - } - - // traceId - final String traceId = WebUtils.getTraceId(exchange); - // LogService.setBizId(traceId); - ThreadContext.put(Consts.TRACE_ID, traceId); - - LOGGER.debug("{} matched api in aggregation: {}", traceId, path); - - // 客户端提交上来的信息 - Map clientInput = new HashMap<>(); - clientInput.put("path", path); - clientInput.put("method", method); - clientInput.put("headers", headers); - clientInput.put("params", MapUtil.toHashMap(request.getQueryParams())); - clientInput.put("contentType", request.getHeaders().getFirst(CommonConstants.HEADER_CONTENT_TYPE)); - - Mono result = null; - MediaType contentType = request.getHeaders().getContentType(); - - if (MediaType.MULTIPART_FORM_DATA.isCompatibleWith(contentType)) { - result = exchange.getMultipartData().flatMap(md -> { - Map filePartMap = new HashMap<>(); - clientInput.put("body", MapUtil.extractFormData(md, CommonConstants.FILE_KEY_PREFIX, filePartMap)); - clientInput.put("filePartMap", filePartMap); - return pipeline.run(input, clientInput, traceId); - }); - } else if (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(contentType)) { - result = exchange.getFormData().flatMap(fd -> { - clientInput.put("body", MapUtil.toHashMap(fd)); - return pipeline.run(input, clientInput, traceId); - }); - } else { - if (HttpMethod.POST.name().equalsIgnoreCase(method)) { - result = DataBufferUtils.join(request.getBody()).defaultIfEmpty(NettyDataBufferUtils.EMPTY_DATA_BUFFER).flatMap(buf -> { - if (buf != NettyDataBufferUtils.EMPTY_DATA_BUFFER) { - try { - clientInput.put("body", buf.toString(StandardCharsets.UTF_8)); - } finally { - DataBufferUtils.release(buf); - } - } - return pipeline.run(input, clientInput, traceId); - }); - } else { - result = pipeline.run(input, clientInput, traceId); - } - } - return result.subscribeOn(Schedulers.elastic()).flatMap(aggResult -> { - // LogService.setBizId(traceId); - ThreadContext.put(Consts.TRACE_ID, traceId); - if (aggResult.getHttpStatus() != null) { - serverHttpResponse.setRawStatusCode(aggResult.getHttpStatus()); - } - String jsonString = null; - if (aggResult.getBody() instanceof String) { - jsonString = (String) aggResult.getBody(); - } else { - if (this.aggregateFilterProperties.isWriteMapNullValue()) { - jsonString = JSON.toJSONString(aggResult.getBody(), SerializerFeature.WriteMapNullValue); - } else { - jsonString = JSON.toJSONString(aggResult.getBody()); - } - } - LOGGER.debug("{} response body: {}", traceId, jsonString); - if (aggResult.getHeaders() != null && !aggResult.getHeaders().isEmpty()) { - serverHttpResponse.getHeaders().addAll(aggResult.getHeaders()); - serverHttpResponse.getHeaders().remove(CommonConstants.HEADER_CONTENT_LENGTH); - } - if (!serverHttpResponse.getHeaders().containsKey(CommonConstants.HEADER_CONTENT_TYPE)) { - // default content-type - serverHttpResponse.getHeaders().add(CommonConstants.HEADER_CONTENT_TYPE, CommonConstants.CONTENT_TYPE_JSON); - } - List headerTraceIds = serverHttpResponse.getHeaders().get(systemConfig.fizzTraceIdHeader()); - if (headerTraceIds == null || !headerTraceIds.contains(traceId)) { - serverHttpResponse.getHeaders().add(systemConfig.fizzTraceIdHeader(), traceId); - } - - long end = System.currentTimeMillis(); - pipeline.getStepContext().addElapsedTime("总耗时", end - start); - LOGGER.info("{} ElapsedTimes={}", traceId, JSON.toJSONString(pipeline.getStepContext().getElapsedTimes())); - - return serverHttpResponse - .writeWith(Flux.just(exchange.getResponse().bufferFactory().wrap(jsonString.getBytes()))); - }); - - } - -} \ No newline at end of file diff --git a/fizz-core/src/main/java/com/fizzgate/filter/AggregateFilterProperties.java b/fizz-core/src/main/java/com/fizzgate/filter/AggregateFilterProperties.java deleted file mode 100644 index 1063af5..0000000 --- a/fizz-core/src/main/java/com/fizzgate/filter/AggregateFilterProperties.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.filter; - -import lombok.Data; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.stereotype.Component; - -import com.fizzgate.context.config.annotation.FizzRefreshScope; - -/** - * {@link AggregateFilter} properties - * - * @author zhongjie - */ -//@RefreshScope -@FizzRefreshScope -@Component -@Data -public class AggregateFilterProperties { - - @Value("${need-auth:true}") - private boolean needAuth; - - @Value("${fizz.aggregate.writeMapNullValue:false}") - private boolean writeMapNullValue; -} diff --git a/fizz-core/src/main/java/com/fizzgate/filter/FilterExceptionHandlerConfig.java b/fizz-core/src/main/java/com/fizzgate/filter/FilterExceptionHandlerConfig.java index e773488..83d1e90 100644 --- a/fizz-core/src/main/java/com/fizzgate/filter/FilterExceptionHandlerConfig.java +++ b/fizz-core/src/main/java/com/fizzgate/filter/FilterExceptionHandlerConfig.java @@ -17,6 +17,12 @@ package com.fizzgate.filter; +import com.fizzgate.Fizz; +import com.fizzgate.aggregate.web.util.AggregateExceptionHandleUtils; +import com.fizzgate.config.SystemConfig; +import com.fizzgate.util.Consts; +import com.fizzgate.util.ThreadContext; +import com.fizzgate.util.WebUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,23 +36,8 @@ import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebExceptionHandler; - -import com.fizzgate.Fizz; -import com.fizzgate.config.SystemConfig; -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.exception.RedirectException; -import com.fizzgate.exception.StopAndResponseException; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.legacy.RespEntity; -import com.fizzgate.util.Consts; -import com.fizzgate.util.JacksonUtils; -import com.fizzgate.util.ThreadContext; -import com.fizzgate.util.WebUtils; - import reactor.core.publisher.Mono; -import java.net.URI; - /** * @author hongqiaowei */ @@ -84,53 +75,14 @@ public class FilterExceptionHandlerConfig { respHeaders.set(WebUtils.BODY_ENCRYPT, Consts.S.FALSE0); } - if (t instanceof StopAndResponseException) { - StopAndResponseException ex = (StopAndResponseException) t; - if (ex.getData() != null) { - respHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - return resp.writeWith(Mono.just(resp.bufferFactory().wrap(ex.getData().toString().getBytes()))); - } - } - if (t instanceof RedirectException) { - RedirectException ex = (RedirectException) t; - if (ex.getRedirectUrl() != null) { - resp.setStatusCode(HttpStatus.MOVED_PERMANENTLY); - respHeaders.setLocation(URI.create(ex.getRedirectUrl())); - return Mono.empty(); - } + if (AggregateExceptionHandleUtils.needHandle(t)) { + return AggregateExceptionHandleUtils.handle(exchange, respHeaders, resp, t, traceId, LOGGER); } String tMsg = t.getMessage(); if (tMsg == null) { tMsg = t.toString(); } - if (t instanceof ExecuteScriptException) { - ExecuteScriptException ex = (ExecuteScriptException) t; - respHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - RespEntity rs = null; - if (ex.getStepContext() != null && ex.getStepContext().returnContext()) { - rs = new RespEntity(HttpStatus.INTERNAL_SERVER_ERROR.value(), tMsg, traceId, ex.getStepContext()); - return resp.writeWith(Mono.just(resp.bufferFactory().wrap(JacksonUtils.writeValueAsBytes(rs)))); - } else { - rs = new RespEntity(HttpStatus.INTERNAL_SERVER_ERROR.value(), tMsg, traceId); - return resp.writeWith(Mono.just(resp.bufferFactory().wrap(rs.toString().getBytes()))); - } - } - - if (t instanceof FizzRuntimeException) { - FizzRuntimeException ex = (FizzRuntimeException) t; - org.apache.logging.log4j.ThreadContext.put(Consts.TRACE_ID, traceId); - LOGGER.error(tMsg, ex); - respHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); - RespEntity rs = null; - if (ex.getStepContext() != null && ex.getStepContext().returnContext()) { - rs = new RespEntity(HttpStatus.INTERNAL_SERVER_ERROR.value(), tMsg, traceId, ex.getStepContext()); - return resp.writeWith(Mono.just(resp.bufferFactory().wrap(JacksonUtils.writeValueAsString(rs).getBytes()))); - } else { - rs = new RespEntity(HttpStatus.INTERNAL_SERVER_ERROR.value(), tMsg, traceId); - return resp.writeWith(Mono.just(resp.bufferFactory().wrap(rs.toString().getBytes()))); - } - } Mono vm; Object fc = exchange.getAttribute(WebUtils.FILTER_CONTEXT); diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/AggregateResource.java b/fizz-core/src/main/java/com/fizzgate/fizz/AggregateResource.java deleted file mode 100644 index bd5f4a4..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/AggregateResource.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz; - -import com.fizzgate.fizz.input.Input; - -/** - * - * @author Francis Dong - * - */ -public class AggregateResource { - - private Pipeline pipeline; - private Input input; - - public AggregateResource(Pipeline pipeline, Input input) { - super(); - this.pipeline = pipeline; - this.input = input; - } - - public Pipeline getPipeline() { - return pipeline; - } - - public void setPipeline(Pipeline pipeline) { - this.pipeline = pipeline; - } - - public Input getInput() { - return input; - } - - public void setInput(Input input) { - this.input = input; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/AggregateResult.java b/fizz-core/src/main/java/com/fizzgate/fizz/AggregateResult.java deleted file mode 100644 index 199735a..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/AggregateResult.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import org.springframework.util.MultiValueMap; - -/** - * - * @author Francis Dong - * - */ -public class AggregateResult { - - private Integer httpStatus; - - private MultiValueMap headers; - - private Object body; - - private StepContext stepContext; - - public MultiValueMap getHeaders() { - return headers; - } - - public void setHeaders(MultiValueMap headers) { - this.headers = headers; - } - - public Object getBody() { - return body; - } - - public void setBody(Object body) { - this.body = body; - } - - public StepContext getStepContext() { - return stepContext; - } - - public void setStepContext(StepContext stepContext) { - this.stepContext = stepContext; - } - - public Integer getHttpStatus() { - return httpStatus; - } - - public void setHttpStatus(Integer httpStatus) { - this.httpStatus = httpStatus; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/AggregateService.java b/fizz-core/src/main/java/com/fizzgate/fizz/AggregateService.java deleted file mode 100644 index 763e88c..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/AggregateService.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.config.SystemConfig; -import com.fizzgate.fizz.input.Input; -import com.fizzgate.util.Consts; -import com.fizzgate.util.MapUtil; -import com.fizzgate.util.Utils; -import com.fizzgate.util.WebUtils; - -import org.apache.logging.log4j.ThreadContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.core.io.buffer.DataBuffer; -import org.springframework.http.HttpHeaders; -import org.springframework.http.server.reactive.ServerHttpResponse; -import org.springframework.stereotype.Service; -import org.springframework.util.MultiValueMap; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; - -import javax.annotation.Resource; -import java.nio.charset.StandardCharsets; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author hongqiaowei - */ - -@Service -public class AggregateService { - - private static final Logger log = LoggerFactory.getLogger(AggregateService.class); - - @Resource - private ConfigLoader aggregateResourceLoader; - - @Resource - private SystemConfig systemConfig; - - public Mono request(String traceId, String clientReqPathPrefix, String method, String service, String path, MultiValueMap queryParams, - HttpHeaders headers, String body) { - - // long start = System.currentTimeMillis(); - // ServerHttpRequest request = exchange.getRequest(); - String pash = clientReqPathPrefix + service + path; - // String method = request.getMethodValue(); - AggregateResource aggregateResource = aggregateResourceLoader.matchAggregateResource(method, pash); - if (aggregateResource == null) { - return Mono.error(Utils.runtimeExceptionWithoutStack("no aggregate resource: " + method + ' ' + pash)); - } else { - Pipeline pipeline = aggregateResource.getPipeline(); - Input input = aggregateResource.getInput(); - Map hs = MapUtil.toHashMap(headers); - // LogService.setBizId(traceId); - ThreadContext.put(Consts.TRACE_ID, traceId); - log.debug("matched aggregation api: {}", pash); - Map clientInput = new HashMap<>(); - clientInput.put("path", pash); - clientInput.put("method", method); - clientInput.put("headers", hs); - // MultiValueMap queryParams = request.getQueryParams(); - if (queryParams != null) { - clientInput.put("params", MapUtil.toHashMap(queryParams)); - } - if (body != null) { - clientInput.put("body", JSON.parse(body)); - } - return pipeline.run(input, clientInput, traceId).subscribeOn(Schedulers.elastic()); - } - } - - public Mono request(String traceId, String clientReqPathPrefix, String method, String service, String path, MultiValueMap queryParams, - HttpHeaders headers, DataBuffer body) { - String b = null; - if (body != null) { - b = body.toString(StandardCharsets.UTF_8); - } - return request(traceId, clientReqPathPrefix, method, service, path, queryParams, headers, b); - } - - public Mono genAggregateResponse(ServerWebExchange exchange, AggregateResult ar) { - ServerHttpResponse clientResp = exchange.getResponse(); - String traceId = WebUtils.getTraceId(exchange); - // LogService.setBizId(traceId); - ThreadContext.put(Consts.TRACE_ID, traceId); - String js = null; - if(ar.getBody() instanceof String) { - js = (String) ar.getBody(); - }else { - js = JSON.toJSONString(ar.getBody()); - } - log.debug("aggregate response body: {}", js); - if (ar.getHeaders() != null && !ar.getHeaders().isEmpty()) { - ar.getHeaders().remove("Content-Length"); - clientResp.getHeaders().addAll(ar.getHeaders()); - } - if (!clientResp.getHeaders().containsKey("Content-Type")) { - // defalut content-type - clientResp.getHeaders().add("Content-Type", "application/json; charset=UTF-8"); - } - List headerTraceIds = clientResp.getHeaders().get(systemConfig.fizzTraceIdHeader()); - if (headerTraceIds == null || !headerTraceIds.contains(traceId)) { - clientResp.getHeaders().add(systemConfig.fizzTraceIdHeader(), traceId); - } - // long end = System.currentTimeMillis(); - // pipeline.getStepContext().addElapsedTime("总耗时", end - start); - // log.info("ElapsedTimes={}", JSON.toJSONString(pipeline.getStepContext().getElapsedTimes())); - return clientResp - .writeWith(Flux.just(exchange.getResponse().bufferFactory().wrap(js.getBytes()))); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/ConfigLoader.java b/fizz-core/src/main/java/com/fizzgate/fizz/ConfigLoader.java deleted file mode 100644 index 54565a1..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/ConfigLoader.java +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.fizzgate.config.AppConfigProperties; -import com.fizzgate.fizz.input.ClientInputConfig; -import com.fizzgate.fizz.input.Input; -import com.fizzgate.fizz.input.InputFactory; -import com.fizzgate.fizz.input.InputType; -import com.fizzgate.util.Consts; -import com.fizzgate.util.ReactorUtils; - -import org.apache.commons.io.FileUtils; -import org.apache.logging.log4j.ThreadContext; -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.data.redis.core.ReactiveStringRedisTemplate; -import org.springframework.stereotype.Component; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -import javax.annotation.PostConstruct; -import javax.annotation.Resource; -import java.io.File; -import java.io.IOException; -import java.io.Serializable; -import java.lang.ref.SoftReference; -import java.nio.charset.StandardCharsets; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -import static com.fizzgate.config.AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_TEMPLATE; -import static com.fizzgate.util.Consts.S.FORWARD_SLASH; -import static com.fizzgate.util.Consts.S.FORWARD_SLASH_STR; - -/** - * - * @author Francis Dong - * @author zhongjie - * - */ -@Component -public class ConfigLoader { - /** - * legacy aggregate formal path prefix - */ - private static final String LEGACY_FORMAL_PATH_PREFIX = "/proxy"; - /** - * legacy aggregate test path prefix - */ - private static final String LEGACY_TEST_PATH_PREFIX = "/proxytest"; - /** - * aggregate test path prefix - */ - private static final String TEST_PATH_PREFIX = "/_proxytest"; - /** - * aggregate test path service name start index - */ - private static final int TEST_PATH_SERVICE_NAME_START_INDEX = TEST_PATH_PREFIX.length() + 1; - - @Autowired - public ConfigurableApplicationContext appContext; - private static final Logger LOGGER = LoggerFactory.getLogger(ConfigLoader.class); - - /** - * 聚合配置存放Hash的Key - */ - private static final String AGGREGATE_HASH_KEY = "fizz_aggregate_config"; - - private static Map aggregateResources = null; - private static Map resourceKey2ConfigInfoMap = null; - private static Map aggregateId2ResourceKeyMap = null; - - @Resource - private AppConfigProperties appConfigProperties; - - @Resource(name = AGGREGATE_REACTIVE_REDIS_TEMPLATE) - private ReactiveStringRedisTemplate reactiveStringRedisTemplate; - - @Resource - private ConfigLoaderProperties configLoaderProperties; - - private String formalPathPrefix; - private int formalPathServiceNameStartIndex; - - public Input createInput(String configStr) throws IOException { - ONode cfgNode = ONode.loadStr(configStr); - - Input input = new Input(); - input.setName(cfgNode.select("$.name").getString()); - - ClientInputConfig clientInputConfig = new ClientInputConfig(); - clientInputConfig.setDataMapping(cfgNode.select("$.dataMapping").toObject(Map.class)); - clientInputConfig.setHeaders(cfgNode.select("$.headers").toObject(Map.class)); - clientInputConfig.setMethod(cfgNode.select("$.method").getString()); - clientInputConfig.setPath(cfgNode.select("$.path").getString()); - if (clientInputConfig.getPath().startsWith(TEST_PATH_PREFIX)) { - // always enable debug for testing - clientInputConfig.setDebug(true); - } else { - if (cfgNode.select("$.debug") != null) { - clientInputConfig.setDebug(cfgNode.select("$.debug").getBoolean()); - } - } - clientInputConfig.setType(InputType.valueOf(cfgNode.select("$.type").getString())); - clientInputConfig.setLangDef(cfgNode.select("$.langDef").toObject(Map.class)); - clientInputConfig.setBodyDef(cfgNode.select("$.bodyDef").toObject(Map.class)); - clientInputConfig.setHeadersDef(cfgNode.select("$.headersDef").toObject(Map.class)); - clientInputConfig.setParamsDef(cfgNode.select("$.paramsDef").toObject(Map.class)); - clientInputConfig.setScriptValidate(cfgNode.select("$.scriptValidate").toObject(Map.class)); - clientInputConfig.setValidateResponse(cfgNode.select("$.validateResponse").toObject(Map.class)); - clientInputConfig.setContentType(cfgNode.select("$.contentType").getString()); - clientInputConfig.setXmlArrPaths(cfgNode.select("$.xmlArrPaths").getString()); - input.setConfig(clientInputConfig); - return input; - } - - public Pipeline createPipeline(String configStr) throws IOException { - ONode cfgNode = ONode.loadStr(configStr); - - Pipeline pipeline = new Pipeline(); - pipeline.setApplicationContext(appContext); - - List> stepConfigs = cfgNode.select("$.stepConfigs").toObject(List.class); - for (Map stepConfig : stepConfigs) { - // set the specified env URL - this.handleRequestURL(stepConfig); - SoftReference weakPipeline = new SoftReference(pipeline); - Step step = new Step.Builder().read(stepConfig, weakPipeline); - step.setName((String) stepConfig.get("name")); - if (stepConfig.get("stop") != null) { - step.setStop((Boolean) stepConfig.get("stop")); - } else { - step.setStop(false); - } - step.setDataMapping((Map) stepConfig.get("dataMapping")); - pipeline.addStep(step); - } - - return pipeline; - } - - public List getConfigInfo() { - if (aggregateResources == null) { - try { - this.init(); - } catch (Exception e) { - e.printStackTrace(); - } - } - return new ArrayList<>(resourceKey2ConfigInfoMap.values()); - } - - public String getConfigStr(String configId) { - if (aggregateResources == null) { - try { - this.init(); - } catch (Exception e) { - e.printStackTrace(); - } - } - String resourceKey = aggregateId2ResourceKeyMap.get(configId); - if (resourceKey == null) { - return null; - } - return aggregateResources.get(resourceKey); - } - - private void handleRequestURL(Map stepConfig) { - List requests = (List) stepConfig.get("requests"); - for (Object obj : requests) { - Map request = (Map) obj; - String envUrl = (String) request.get(appConfigProperties.getEnv() + "Url"); - if (!StringUtils.isEmpty(envUrl)) { - request.put("url", request.get(appConfigProperties.getEnv() + "Url")); - } - } - } - - @PostConstruct - public synchronized void init() throws Exception { - this.refreshLocalCache(); - InputFactory.loadInputClasses(); - } - - - public synchronized void refreshLocalCache() throws Exception { - if (formalPathPrefix == null) { - String formalPathPrefixTmp = appContext.getEnvironment().getProperty("gateway.prefix", "/proxy"); - if (formalPathPrefixTmp.endsWith(FORWARD_SLASH_STR)) { - // remove the end slash - formalPathPrefixTmp = formalPathPrefixTmp.substring(0, formalPathPrefixTmp.length() - 1); - } - formalPathPrefix = formalPathPrefixTmp; - formalPathServiceNameStartIndex = formalPathPrefix.length() + 1; - } - - Map aggregateResourcesTmp = new ConcurrentHashMap<>(1024); - Map resourceKey2ConfigInfoMapTmp = new ConcurrentHashMap<>(1024); - Map aggregateId2ResourceKeyMapTmp = new ConcurrentHashMap<>(1024); - - if (configLoaderProperties.getReadLocalConfigFlag()) { - File dir = new File("json"); - if (dir.exists() && dir.isDirectory()) { - File[] files = dir.listFiles(); - if (files != null && files.length > 0) { - for (File file : files) { - if (!file.exists()) { - throw new IOException("File not found"); - } - String configStr = FileUtils.readFileToString(file, StandardCharsets.UTF_8); - this.addConfig(configStr, aggregateResourcesTmp, resourceKey2ConfigInfoMapTmp, aggregateId2ResourceKeyMapTmp); - } - } - } - } else { - // 从Redis缓存中获取配置 - final Throwable[] throwable = new Throwable[1]; - Throwable error = Mono.just(Objects.requireNonNull(reactiveStringRedisTemplate.opsForHash().entries(AGGREGATE_HASH_KEY) - .defaultIfEmpty(new AbstractMap.SimpleEntry<>(ReactorUtils.OBJ, ReactorUtils.OBJ)).onErrorStop().doOnError(t -> LOGGER.info(null, t)) - .concatMap(entry -> { - Object k = entry.getKey(); - if (k == ReactorUtils.OBJ) { - return Flux.just(entry); - } - String configStr = (String) entry.getValue(); - // LOGGER.info("aggregate config: " + k.toString() + Consts.S.COLON + configStr, LogService.BIZ_ID, k.toString()); - - ThreadContext.put(Consts.TRACE_ID, k.toString()); - LOGGER.info("aggregate config: " + k.toString() + Consts.S.COLON + configStr); - - try { - this.addConfig(configStr, aggregateResourcesTmp, resourceKey2ConfigInfoMapTmp, aggregateId2ResourceKeyMapTmp); - return Flux.just(entry); - } catch (Throwable t) { - throwable[0] = t; - LOGGER.info(configStr, t); - return Flux.error(t); - } - }).blockLast())).flatMap( - e -> { - if (throwable[0] != null) { - return Mono.error(throwable[0]); - } - return Mono.just(ReactorUtils.EMPTY_THROWABLE); - } - ).block(); - if (error != ReactorUtils.EMPTY_THROWABLE) { - assert error != null; - throw new RuntimeException(error); - } - } - - aggregateResources = aggregateResourcesTmp; - resourceKey2ConfigInfoMap = resourceKey2ConfigInfoMapTmp; - aggregateId2ResourceKeyMap = aggregateId2ResourceKeyMapTmp; - } - - public synchronized void addConfig(String configStr) { - if (aggregateResources == null) { - try { - this.init(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - this.addConfig(configStr, aggregateResources, resourceKey2ConfigInfoMap, aggregateId2ResourceKeyMap); - } - - private void addConfig(String configStr, Map aggregateResources, - Map resourceKey2ConfigInfoMap, Map aggregateId2ResourceKeyMap) { - ONode cfgNode = ONode.loadStr(configStr); - - boolean needReGenConfigStr = false; - // in the future aggregate config will add this field and remove the prefix '/proxy'|'/proxytest' of path - boolean existAggrVersion = cfgNode.contains("aggrVersion"); - - String method = cfgNode.select("$.method").getString(); - String path = cfgNode.select("$.path").getString(); - - if (!existAggrVersion) { - if (path.startsWith(LEGACY_TEST_PATH_PREFIX)) { - // legacy test path, remove prefix '/proxytest' - path = path.replaceFirst(LEGACY_TEST_PATH_PREFIX, TEST_PATH_PREFIX); - needReGenConfigStr = true; - } else if (path.startsWith(LEGACY_FORMAL_PATH_PREFIX)) { - // legacy formal path, remove prefix '/proxy' - path = path.replace(LEGACY_FORMAL_PATH_PREFIX, ""); - needReGenConfigStr = true; - } - } - - if (!path.startsWith(TEST_PATH_PREFIX)) { - // formal path add the custom gateway prefix - path = String.format("%s%s", formalPathPrefix, path); - needReGenConfigStr = true; - } - - String resourceKey = method.toUpperCase() + ":" + path; - String configId = cfgNode.select("$.id").getString(); - String configName = cfgNode.select("$.name").getString(); - long version = cfgNode.select("$.version").getLong(); - - if (needReGenConfigStr) { - cfgNode.set("path", path); - configStr = cfgNode.toJson(); - } - - LOGGER.debug("add aggregation config, key={} config={}", resourceKey, configStr); - if (StringUtils.hasText(configId)) { - String existResourceKey = aggregateId2ResourceKeyMap.get(configId); - if (StringUtils.hasText(existResourceKey)) { - // 删除旧有的配置 - aggregateResources.remove(existResourceKey); - resourceKey2ConfigInfoMap.remove(existResourceKey); - } - aggregateId2ResourceKeyMap.put(configId, resourceKey); - } - aggregateResources.put(resourceKey, configStr); - resourceKey2ConfigInfoMap.put(resourceKey, this.buildConfigInfo(configId, configName, method, path, version)); - } - - public synchronized void deleteConfig(String configIds) { - if (CollectionUtils.isEmpty(aggregateId2ResourceKeyMap)) { - return; - } - - JSONArray idArray = JSON.parseArray(configIds); - idArray.forEach(it -> { - String configId = (String) it; - String existResourceKey = aggregateId2ResourceKeyMap.get(configId); - if (StringUtils.hasText(existResourceKey)) { - LOGGER.debug("delete aggregation config: {}", existResourceKey); - aggregateResources.remove(existResourceKey); - resourceKey2ConfigInfoMap.remove(existResourceKey); - aggregateId2ResourceKeyMap.remove(configId); - } - }); - } - - public AggregateResource matchAggregateResource(String method, String path) { - if (aggregateResources == null) { - try { - init(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } - String key = method.toUpperCase() + ":" + path; - // config file entry ,if you want modify the aggregate config json but not use the interface of fizz, - // you can just read the config ,transform to json format and modify it - if (aggregateResources.containsKey(key) && aggregateResources.get(key) != null) { - String configStr = aggregateResources.get(key); - Input input = null; - Pipeline pipeline = null; - try { - input = createInput(configStr); - pipeline = createPipeline(configStr); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - if (pipeline != null && input != null) { - ClientInputConfig cfg = (ClientInputConfig) input.getConfig(); - return new AggregateResource(pipeline, input); - } - } - return null; - } - - private ConfigInfo buildConfigInfo(String configId, String configName, String method, String path, long version) { - String serviceName = this.extractServiceName(path); - ConfigInfo configInfo = new ConfigInfo(); - configInfo.setConfigId(configId); - configInfo.setConfigName(configName); - configInfo.setServiceName(serviceName); - configInfo.setMethod(method); - configInfo.setPath(path); - configInfo.setVersion(version == 0 ? null : version); - return configInfo; - } - - private String extractServiceName(String path) { - if (path != null) { - if (path.startsWith(TEST_PATH_PREFIX)) { - int endIndex = path.indexOf(FORWARD_SLASH, TEST_PATH_SERVICE_NAME_START_INDEX); - if (endIndex > TEST_PATH_SERVICE_NAME_START_INDEX) { - return path.substring(TEST_PATH_SERVICE_NAME_START_INDEX, endIndex); - } - } else if (path.startsWith(formalPathPrefix)) { - int endIndex = path.indexOf(FORWARD_SLASH, formalPathServiceNameStartIndex); - if (endIndex > formalPathServiceNameStartIndex) { - return path.substring(formalPathServiceNameStartIndex, endIndex); - } - } - } - return null; - } - - public static class ConfigInfo implements Serializable { - private static final long serialVersionUID = 1L; - /** - * 配置ID - */ - private String configId; - - /** - * 配置名 - */ - private String configName; - - /** - * 服务名 - */ - private String serviceName; - /** - * 接口请求method类型 - */ - private String method; - /** - * 接口请求路径 - */ - private String path; - /** - * 版本号 - */ - private Long version; - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ConfigInfo that = (ConfigInfo) o; - return Objects.equals(configId, that.configId) && Objects.equals(configName, that.configName) - && Objects.equals(serviceName, that.serviceName) && Objects.equals(method, that.method) - && Objects.equals(path, that.path) && Objects.equals(version, that.version); - } - - @Override - public int hashCode() { - return Objects.hash(configId, configName, serviceName, method, path, version); - } - - public String getConfigId() { - return configId; - } - - public void setConfigId(String configId) { - this.configId = configId; - } - - public String getConfigName() { - return configName; - } - - public void setConfigName(String configName) { - this.configName = configName; - } - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getMethod() { - return method; - } - - public void setMethod(String method) { - this.method = method; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public Long getVersion() { - return version; - } - - public void setVersion(Long version) { - this.version = version; - } - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/ConfigLoaderProperties.java b/fizz-core/src/main/java/com/fizzgate/fizz/ConfigLoaderProperties.java deleted file mode 100644 index 3e6cd7f..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/ConfigLoaderProperties.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz; - -import lombok.Data; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.cloud.context.config.annotation.RefreshScope; -import org.springframework.stereotype.Component; - -/** - * {@link ConfigLoader} properties - * - * @author zhongjie - */ -@RefreshScope -@Component -@Data -public class ConfigLoaderProperties { - - @Value("${fizz.aggregate.read-local-config-flag:false}") - private Boolean readLocalConfigFlag; -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/Pipeline.java b/fizz-core/src/main/java/com/fizzgate/fizz/Pipeline.java deleted file mode 100644 index db5e4c9..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/Pipeline.java +++ /dev/null @@ -1,585 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.exception.RedirectException; -import com.fizzgate.exception.StopAndResponseException; -import com.fizzgate.fizz.component.ComponentExecutor; -import com.fizzgate.fizz.component.ComponentResult; -import com.fizzgate.fizz.component.IComponent; -import com.fizzgate.fizz.component.StepContextPosition; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.field.FieldConfig; -import com.fizzgate.fizz.field.ValueTypeEnum; -import com.fizzgate.fizz.input.*; -import com.fizzgate.util.Consts; -import com.fizzgate.util.JacksonUtils; -import com.fizzgate.util.JsonSchemaUtils; -import com.fizzgate.util.MapUtil; -import com.fizzgate.xml.JsonToXml; -import com.fizzgate.xml.XmlToJson; -import com.fizzgate.xml.XmlToJson.Builder; - -import org.apache.logging.log4j.ThreadContext; -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.data.util.Pair; -import org.springframework.http.HttpHeaders; -import org.springframework.http.codec.multipart.FilePart; -import org.springframework.util.CollectionUtils; -import org.springframework.util.StringUtils; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import com.fizzgate.schema.util.I18nUtils; -import com.fizzgate.schema.util.PropertiesSupportUtils; - -import javax.script.ScriptException; -import java.util.*; - -/** - * - * @author linwaiwai - * @author Francis Dong - * @author zhongjie - * - */ -public class Pipeline { - private static final String CONTENT_TYPE_XML = "application/xml"; - private ConfigurableApplicationContext applicationContext; - private static final Logger LOGGER = LoggerFactory.getLogger(Pipeline.class); - private LinkedList steps = new LinkedList(); - private StepContext stepContext = new StepContext<>(); - public void addStep(Step step) { - steps.add(step); - } - - static void displayValue(String n) { - System.out.println("input : " + n); - } - - public StepContext getStepContext(){ - return this.stepContext; - } - - public Mono run(Input input, Map clientInput, String traceId) { - return this.runPipeline(input, clientInput, traceId).onErrorResume((ex) -> { - String message = ex.getMessage(); - if (ex.getMessage() == null) { - message = "failed to run aggregation pipeline, message: " + ex.toString(); - StackTraceElement[] stacks = ex.getStackTrace(); - if (stacks != null && stacks.length > 0) { - message = message + " at " + stacks[0]; - } - } - if (ex instanceof StopAndResponseException) { - throw (StopAndResponseException) ex; - } - if (ex instanceof RedirectException) { - throw (RedirectException) ex; - } - if (ex instanceof ExecuteScriptException) { - throw (ExecuteScriptException) ex; - } - if (ex instanceof FizzRuntimeException && ex.getMessage() != null) { - FizzRuntimeException e = (FizzRuntimeException) ex; - if (e.getStepContext() == null) { - e.setStepContext(stepContext); - } - throw e; - } else { - throw new FizzRuntimeException(message, ex, stepContext); - } - }); - } - - public Mono runPipeline(Input input, Map clientInput, String traceId) { - ClientInputConfig config = (ClientInputConfig)input.getConfig(); - this.initialStepContext(clientInput, config); - this.stepContext.setDebug(config.isDebug()); - this.stepContext.setApplicationContext(applicationContext); - - if(traceId != null) { - this.stepContext.setTraceId(traceId); - } - - long t1 = System.currentTimeMillis(); - - @SuppressWarnings("unchecked") - String validateMsg = this.inputValidate(input, - (Map)((Map)this.stepContext.get("input")).get("request")); - - this.stepContext.addElapsedTime("入参校验", System.currentTimeMillis()-t1); - - if (StringUtils.hasText(validateMsg)) { - long t2 = System.currentTimeMillis(); - // 将验证错误信息放入上下文 - stepContext.put("validateMsg", validateMsg); - Map validateResponse = config.getValidateResponse(); - // 数据转换 - AggregateResult aggregateResult = this.doInputDataMapping(input, validateResponse); - this.stepContext.addElapsedTime("入参校验结果转换", System.currentTimeMillis() - t2); - return Mono.just(aggregateResult); - } - - if(CollectionUtils.isEmpty(steps)) { - return handleOutput(input); - }else { - LinkedList opSteps = (LinkedList) steps.clone(); - Step step1 = opSteps.removeFirst(); - Mono> result = runStep(step1, null).expand(lastStepResponse -> { - if (opSteps.isEmpty() || lastStepResponse.isStop()) { - return Mono.empty(); - } - Step step = opSteps.pop(); - return runStep(step, lastStepResponse); - }).flatMap(response -> Flux.just(response)).collectList(); - return result.flatMap(clientResponse -> { - return handleOutput(input); - }); - } - } - - private Mono runStep(Step step, StepResponse lastStepResponse){ - StepResponse stepResponse = new StepResponse(step, null, new HashMap>()); - stepContext.put(step.getName(), stepResponse); - List components = step.getComponents(); - if (components != null && components.size() > 0) { - StepContextPosition stepCtxPos = new StepContextPosition(step.getName()); - return ComponentExecutor.exec(components, stepContext, stepCtxPos, (ctx, pos) -> { - step.beforeRun(stepContext, null); - return createStep(step); - }).flatMap(sr -> { - if (sr instanceof ComponentResult) { - return Mono.just(stepResponse); - } else { - return Mono.just((StepResponse) sr); - } - }); - } else { - step.beforeRun(stepContext, null); - return createStep(step); - } - } - - private Mono handleOutput(Input input){ - // 数据转换 - long t3 = System.currentTimeMillis(); - AggregateResult aggResult = this.doInputDataMapping(input, null); - this.stepContext.addElapsedTime(input.getName()+"聚合接口响应结果数据转换", System.currentTimeMillis() - t3); - if(this.stepContext.isDebug() || LOGGER.isDebugEnabled()) { - // LogService.setBizId(this.stepContext.getTraceId()); - ThreadContext.put(Consts.TRACE_ID, this.stepContext.getTraceId()); - String jsonString = JSON.toJSONString(aggResult); - if(LOGGER.isDebugEnabled()) { - LOGGER.debug("aggResult {}", jsonString); - LOGGER.debug("stepContext {}", JSON.toJSONString(stepContext)); - }else { - LOGGER.info("aggResult {}", jsonString); - LOGGER.info("stepContext {}", JSON.toJSONString(stepContext)); - } - } - return Mono.just(aggResult); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Mono createStep(Step step) { - long start = System.currentTimeMillis(); - List monos = step.run(); - Mono[] monoArray = monos.stream().toArray(Mono[]::new); - Monoresult = Flux.merge(monoArray).reduce(new HashMap(), (item1, item2) -> { - if (item2.isEmpty()) { - return item1; - } - Input input = (Input)item2.get("request"); - item1.put(input.getName() , item2.get("data")); - return item1; - }).flatMap(item -> { - // stepResult 数据转换 - long t1 = System.currentTimeMillis(); - StepResponse stepResponse = this.doStepDataMapping(step); - stepResponse.setStop(step.isStop()); - long t2 = System.currentTimeMillis(); - this.stepContext.addElapsedTime(step.getName() + "结果数据转换", t2 - t1); - this.stepContext.addElapsedTime(step.getName() + "耗时", System.currentTimeMillis() - start); - - return Mono.just(stepResponse); - }); - return result; - } - - /** - * 初始化上下文 - * @param clientInput 客户端提交上来的信息 - */ - public void initialStepContext(Map clientInput, ClientInputConfig config) { - Map input = new HashMap<>(); - Map inputRequest = new HashMap<>(); - Map inputResponse = new HashMap<>(); - input.put("request", inputRequest); - input.put("response", inputResponse); - if(clientInput != null) { - inputRequest.put("path", clientInput.get("path")); - inputRequest.put("method", clientInput.get("method")); - inputRequest.put("headers", clientInput.get("headers")); - inputRequest.put("params", clientInput.get("params")); - stepContext.addFilePartMap((Map) clientInput.get("filePartMap")); - - if (CONTENT_TYPE_XML.equals(config.getContentType()) || (StringUtils.isEmpty(config.getContentType()) - && isXmlContentType((String) clientInput.get("contentType")))) { - String[] paths = null; - if (!StringUtils.isEmpty(config.getXmlArrPaths())) { - paths = config.getXmlArrPaths().split(","); - } - Builder builder = new XmlToJson.Builder((String) clientInput.get("body")); - if (paths != null && paths.length > 0) { - for (int j = 0; j < paths.length; j++) { - String p = paths[j]; - builder = builder.forceList(p); - } - } - inputRequest.put("body", builder.build().toJson().toMap()); - } else if (clientInput.get("body") instanceof Map) { - inputRequest.put("body", clientInput.get("body")); - } else { - inputRequest.put("body", JSON.parse((String) clientInput.get("body"))); - } - } - stepContext.put("input", input); - } - - private boolean isXmlContentType(String contentType) { - if (contentType != null) { - String[] cts = contentType.split(";"); - for (int i = 0; i < cts.length; i++) { - if (CONTENT_TYPE_XML.equals(cts[i])) { - return true; - } - } - } - return false; - } - - @SuppressWarnings("unchecked") - private StepResponse doStepDataMapping(Step step) { - StepResponse stepResponse = (StepResponse)stepContext.get(step.getName()); - if (step.getDataMapping() != null) { - Map responseMapping = (Map) step.getDataMapping().get("response"); - if(responseMapping != null && !StringUtils.isEmpty(responseMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - - // body - stepResponse.setResult(PathMapping.transform(ctxNode, stepContext, - (Map) responseMapping.get("fixedBody"), - (Map) responseMapping.get("body"))); - - // script - if(responseMapping.get("script") != null) { - Map scriptCfg = (Map) responseMapping.get("script"); - try { - Map stepBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext, Map.class); - if(stepBody != null) { - stepResponse.setResult(stepBody); - } - } catch (ScriptException e) { - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - } - } - return stepResponse; - } - - /** - * 当validateResponse不为空表示验参失败,使用该配置响应数据 - */ - @SuppressWarnings("unchecked") - private AggregateResult doInputDataMapping(Input input, Map validateResponse) { - AggregateResult aggResult = new AggregateResult(); - Map> group = (Map>) stepContext.get("input"); - if(group == null) { - group = new HashMap>(); - stepContext.put("input", group); - } - Map response = null; - if(group.get("response") == null) { - response = new HashMap<>(); - group.put("response", response); - } - response = group.get("response"); - String respContentType = null; - int statusCode = 200; - if (input != null && input.getConfig() != null && input.getConfig().getDataMapping() != null) { - Map responseMapping = (Map) input.getConfig().getDataMapping() - .get("response"); - if (validateResponse != null) { - responseMapping = validateResponse; - } - if (!CollectionUtils.isEmpty(responseMapping)) { - respContentType = (String) responseMapping.get("contentType"); - ONode ctxNode = PathMapping.toONode(stepContext); - // HttpStatus - if (validateResponse == null) { - if (responseMapping.get("httpStatus") != null) { - Map fcMap = (Map) responseMapping.get("httpStatus"); - FieldConfig fc = new FieldConfig(fcMap); - if (ValueTypeEnum.FIXED.equals(fc.getType()) && fc.getValue() != null) { - statusCode = Integer.valueOf(fc.getValue().toString()); - } else if ((ValueTypeEnum.REF.equals(fc.getType()) || ValueTypeEnum.FUNC.equals(fc.getType())) - && fc.getValue() != null) { - String dataType = null; - if (fc.getRefDataType() != null) { - dataType = fc.getRefDataType().getCode(); - } - Object statusCodeObj = PathMapping.getValueByPath(ctxNode, dataType, - (String) fc.getValue()); - statusCode = (statusCodeObj == null) ? statusCode - : Integer.valueOf(statusCodeObj.toString()); - } - } - response.put("httpStatus", statusCode); - } - - // headers - Map headers = PathMapping.transform(ctxNode, stepContext, - MapUtil.upperCaseKey((Map) responseMapping.get("fixedHeaders")), - MapUtil.upperCaseKey((Map) responseMapping.get("headers")), false); - if (headers.containsKey(CommonConstants.WILDCARD_TILDE) - && headers.get(CommonConstants.WILDCARD_TILDE) instanceof Map) { - response.put("headers", headers.get(CommonConstants.WILDCARD_TILDE)); - } else { - response.put("headers", headers); - } - - // body - Map body = PathMapping.transform(ctxNode, stepContext, - (Map) responseMapping.get("fixedBody"), - (Map) responseMapping.get("body")); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - response.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (responseMapping.get("script") != null) { - Map scriptCfg = (Map) responseMapping.get("script"); - try { - Object respBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if(respBody != null) { - body.putAll((Map) respBody); - } - } catch (ScriptException e) { - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - response.put("body", body); - } - } - } - - HttpHeaders httpHeaders = MapUtil.toHttpHeaders((Map) response.get("headers")); - if (CONTENT_TYPE_XML.equals(respContentType) && !httpHeaders.containsKey(CommonConstants.HEADER_CONTENT_TYPE)) { - httpHeaders.add(CommonConstants.HEADER_CONTENT_TYPE.toUpperCase(), CONTENT_TYPE_XML); - response.put(CommonConstants.HEADER_CONTENT_TYPE.toUpperCase(), CONTENT_TYPE_XML); - } - - // convert JSON to XML if it is XML content type - if(CONTENT_TYPE_XML.equals(respContentType)) { - Object respBody = response.get("body"); - response.put("jsonBody", respBody); - JsonToXml jsonToXml = new JsonToXml.Builder(JSON.toJSONString(respBody)).build(); - response.put("body", jsonToXml.toString()); - } - - Object respBody = response.get("body"); - // 测试模式返回StepContext - if (stepContext.returnContext() && respBody instanceof Map) { - Map t = (Map) respBody; - t.put(stepContext.CONTEXT_FIELD, stepContext); - } - - aggResult.setHttpStatus(statusCode); - aggResult.setBody(response.get("body")); - aggResult.setHeaders(httpHeaders); - return aggResult; - } - - private static final String LANGUAGE_CHINESE = "zh"; - private static final String LANGUAGE_ENGLISH = "en"; - enum ValidateType { - /** - * Header - */ - HEADER("请求头", "Header"), - /** - * Query param - */ - QUERY_PARAM("Query参数", "Query param"), - /** - * Body - */ - BODY("请求体", "Body"), - /** - * Script - */ - SCRIPT("脚本校验", "Script"); - - ValidateType(String tipZh, String tipEn) { - this.tipZh = tipZh; - this.tipEn = tipEn; - } - - String tipZh; - String tipEn; - - public String getTip() { - String language = I18nUtils.getContextLocale().getLanguage(); - if (LANGUAGE_CHINESE.equals(language)) { - return tipZh; - } else if (LANGUAGE_ENGLISH.equals(language)) { - return tipEn; - } - return tipZh; - } - } - - String inputValidate(Input input, Map clientInput) { - try { - InputConfig config = input.getConfig(); - if (config instanceof ClientInputConfig) { - Map langDef = ((ClientInputConfig) config).getLangDef(); - this.handleLangDef(langDef); - - Pair> validateTypeAndValidateErrorListPair = - this.doInputValidate((ClientInputConfig) config, clientInput); - if (validateTypeAndValidateErrorListPair == null) { - return null; - } - return String.format("%s: %s", validateTypeAndValidateErrorListPair.getFirst().getTip(), - StringUtils.collectionToCommaDelimitedString(validateTypeAndValidateErrorListPair.getSecond())); - } - return null; - } finally { - I18nUtils.removeContextLocale(); - } - } - - private Pair> doInputValidate(ClientInputConfig config, Map clientInput) { - Map headersDef = config.getHeadersDef(); - if (!CollectionUtils.isEmpty(headersDef)) { - // 验证headers入参是否符合要求 - List errorList; - PropertiesSupportUtils.setContextSupportPropertyUpperCase(); - try { - errorList = JsonSchemaUtils.validateAllowValueStr(JSON.toJSONString(headersDef), - JSON.toJSONString(clientInput.get("headers"))); - } finally { - PropertiesSupportUtils.removeContextSupportPropertyUpperCase(); - } - - if (!CollectionUtils.isEmpty(errorList)) { - return Pair.of(ValidateType.HEADER, errorList); - } - } - - Map paramsDef = config.getParamsDef(); - if (!CollectionUtils.isEmpty(paramsDef)) { - // 验证params入参是否符合要求 - List errorList = JsonSchemaUtils.validateAllowValueStr(JSON.toJSONString(paramsDef), - JSON.toJSONString(clientInput.get("params"))); - if (!CollectionUtils.isEmpty(errorList)) { - return Pair.of(ValidateType.QUERY_PARAM, errorList); - } - } - - Map bodyDef = config.getBodyDef(); - if (!CollectionUtils.isEmpty(bodyDef)) { - // 验证body入参是否符合要求 - List errorList = JsonSchemaUtils.validate(JSON.toJSONString(bodyDef), - JSON.toJSONString(clientInput.get("body"))); - if (!CollectionUtils.isEmpty(errorList)) { - return Pair.of(ValidateType.BODY, errorList); - } - } - - Map scriptValidate = config.getScriptValidate(); - if (!CollectionUtils.isEmpty(scriptValidate)) { - ONode ctxNode = PathMapping.toONode(stepContext); - // 验证入参是否符合脚本要求 - try { - @SuppressWarnings("unchecked") - List errorList = (List) ScriptHelper.execute(scriptValidate, ctxNode, stepContext, List.class); - if (!CollectionUtils.isEmpty(errorList)) { - return Pair.of(ValidateType.SCRIPT, errorList); - } - } catch (ScriptException e) { - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptValidate), e); - throw new ExecuteScriptException(e, stepContext, scriptValidate); - } - } - - return null; - } - - @SuppressWarnings("unchecked") - private void handleLangDef(Map langDef) { - if (!CollectionUtils.isEmpty(langDef)) { - // 存在提示语言定义配置 - Object langParamObj = langDef.get("langParam"); - String langParam = null; - if (langParamObj instanceof String) { - langParam = (String) langParamObj; - } - Object langMappingObj = langDef.get("langMapping"); - Map langMapping = null; - if (langMappingObj instanceof Map) { - langMapping = (Map) langMappingObj; - } - if (langParam != null && !CollectionUtils.isEmpty(langMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - Map langParamMap = new HashMap<>(2); - langParamMap.put("langParam", langParam); - Map transformMap = PathMapping.transform(ctxNode, stepContext, null, langParamMap); - Object langParamValue = transformMap.get("langParam"); - if (langParamValue != null) { - // 判断使用哪种语言 - Object zh = langMapping.get("zh"); - if (zh != null && zh.toString().equals(langParamValue.toString())) { - I18nUtils.setContextLocale(new Locale("zh")); - } - Object en = langMapping.get("en"); - if (en != null && en.toString().equals(langParamValue.toString())) { - I18nUtils.setContextLocale(new Locale("en")); - } - } - } - } - } - - public void setApplicationContext(ConfigurableApplicationContext appContext) { - this.applicationContext = appContext; - } - - public ConfigurableApplicationContext getApplicationContext() { - return this.applicationContext; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/Step.java b/fizz-core/src/main/java/com/fizzgate/fizz/Step.java deleted file mode 100644 index a691aaa..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/Step.java +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import java.lang.ref.SoftReference; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.collections.CollectionUtils; -import org.springframework.context.ConfigurableApplicationContext; - -import com.fizzgate.fizz.component.ComponentExecutor; -import com.fizzgate.fizz.component.ComponentResult; -import com.fizzgate.fizz.component.IComponent; -import com.fizzgate.fizz.component.StepContextPosition; -import com.fizzgate.fizz.input.Input; -import com.fizzgate.fizz.input.InputConfig; -import com.fizzgate.fizz.input.InputContext; -import com.fizzgate.fizz.input.InputFactory; -import com.fizzgate.fizz.input.InputType; - -import reactor.core.publisher.Mono; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class Step { - private SoftReference weakPipeline; - private String name; - - // 是否在执行完当前step就返回 - private boolean stop; - - private Map dataMapping; - - private Map requestConfigs = new HashMap(); - - private List components; - - public List getComponents() { - return components; - } - - public void setComponents(List components) { - this.components = components; - } - - public SoftReference getWeakPipeline() { - return weakPipeline; - } - - public void setWeakPipeline(SoftReference weakPipeline) { - this.weakPipeline = weakPipeline; - } - - public ConfigurableApplicationContext getCurrentApplicationContext() { - return this.getWeakPipeline() != null ? this.getWeakPipeline().get().getApplicationContext(): null; - } - - public static class Builder { - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Step read(Map config, SoftReference weakPipeline) { - Step step = new Step(); - step.setWeakPipeline(weakPipeline); - List requests = (List) config.get("requests"); - if (CollectionUtils.isNotEmpty(requests)) { - for (Map requestConfig : requests) { - InputConfig inputConfig = InputFactory.createInputConfig(requestConfig); - step.addRequestConfig((String) requestConfig.get("name"), inputConfig); - } - } - step.setComponents(ComponentExecutor.buildComponents((List>) config.get("components"))); - return step; - } - } - - private StepContext stepContext; - - public StepContext getStepContext(){ - return this.stepContext; - } - - private StepResponse lastStepResponse = null; - private Map inputs = new HashMap(); - public void beforeRun(StepContext stepContext2, StepResponse response ) { - stepContext = stepContext2; - lastStepResponse = response; - StepResponse stepResponse = (StepResponse) stepContext.get(this.name); - Map configs = this.getRequestConfigs(); - for(String configName :configs.keySet()) { - InputConfig inputConfig = configs.get(configName); - InputType type = inputConfig.getType(); - Input input = InputFactory.createInput(type.toString()); - input.setWeakStep(new SoftReference(this)); - input.setConfig(inputConfig); - input.setName(configName); - input.setStepResponse(stepResponse); - InputContext context = new InputContext(stepContext, lastStepResponse); - input.beforeRun(context); - inputs.put(input.getName(), input); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - public List run() { - List monos = new ArrayList(); - for(String requestName :inputs.keySet()) { - Input input = inputs.get(requestName); - List components = input.getConfig().getComponents(); - if (components != null && components.size() > 0) { - StepContextPosition stepCtxPos = new StepContextPosition(name, requestName); - Mono result = ComponentExecutor.exec(components, stepContext, stepCtxPos, (ctx, pos) -> { - if (input.needRun(ctx)) { - return input.run(); - } - Map inputResult = new HashMap(); - inputResult.put("data", new HashMap()); - inputResult.put("request", input); - return Mono.just(inputResult); - }).flatMap(r -> { - if (r instanceof ComponentResult) { - Map inputResult = new HashMap(); - inputResult.put("data", new HashMap()); - inputResult.put("request", input); - return Mono.just(inputResult); - } else { - return Mono.just(r); - } - }); - monos.add(result); - } else { - if (input.needRun(stepContext)) { - Mono singleMono = input.run(); - monos.add(singleMono); - } - } - } - return monos; - } - - - - public void afeterRun() { - - } - - public InputConfig addRequestConfig(String name, InputConfig requestConfig) { - return requestConfigs.put(name, requestConfig); - } - - - public Map getRequestConfigs() { - return requestConfigs; - } - - - public String getName() { - if (name == null) { - return name = "step" + (int)(Math.random()*100); - } - return name; - } - - - public void setName(String name) { - this.name = name; - } - - public boolean isStop() { - return stop; - } - - public void setStop(boolean stop) { - this.stop = stop; - } - - public Map getDataMapping() { - return dataMapping; - } - - public void setDataMapping(Map dataMapping) { - this.dataMapping = dataMapping; - } - - -} - diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/StepContext.java b/fizz-core/src/main/java/com/fizzgate/fizz/StepContext.java deleted file mode 100644 index 3acce25..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/StepContext.java +++ /dev/null @@ -1,892 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.http.codec.multipart.FilePart; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.constants.CommonConstants; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - * @param - * @param - */ -@SuppressWarnings("unchecked") -public class StepContext extends ConcurrentHashMap { - private ConfigurableApplicationContext applicationContext; - public static final String ELAPSED_TIMES = "elapsedTimes"; - public static final String DEBUG = "debug"; - public static final String RETURN_CONTEXT = "returnContext"; - // context field in response body - public static final String CONTEXT_FIELD = "_context"; - - // exception info - public static final String EXCEPTION_MESSAGE = "exceptionMessage"; - public static final String EXCEPTION_STACKS = "exceptionStacks"; - public static final String EXCEPTION_DATA = "exceptionData"; - - private Map filePartMap = new HashMap<>(); - - public void setDebug(Boolean debug) { - this.put((K)DEBUG, (V)debug); - } - - public String getTraceId() { - return (String) this.get(CommonConstants.TRACE_ID); - } - - public void setTraceId(String traceId) { - this.put((K)CommonConstants.TRACE_ID, (V)traceId); - } - - /** - * 是否调试模式 - * @return - */ - public Boolean isDebug() { - return this.get(DEBUG) == null ? false : (Boolean) this.get(DEBUG); - } - - /** - * 是否在响应体里返回上下文 - * @return - */ - public boolean returnContext() { - return Boolean.valueOf((String)getInputReqHeader(RETURN_CONTEXT)); - } - - public void addFilePart(String key, FilePart filePart) { - this.filePartMap.put(key, filePart); - } - - public void addFilePartMap(Map filePartMap) { - if(filePartMap != null && !filePartMap.isEmpty()) { - this.filePartMap.putAll(filePartMap); - } - } - - public FilePart getFilePart(String key) { - return this.filePartMap.get(key); - } - - public Map getFilePartMap() { - return this.filePartMap; - } - - /** - * set exception information - * @param cause exception - * @param exceptionData data that cause the exception, such as script source code, etc. - */ - public void setExceptionInfo(Throwable cause, Object exceptionData) { - this.put((K) EXCEPTION_MESSAGE, (V) cause.getMessage()); - this.put((K) EXCEPTION_DATA, (V) exceptionData); - - StackTraceElement[] stacks = cause.getStackTrace(); - if (stacks != null && stacks.length > 0) { - String[] arr = new String[stacks.length]; - for (int i = 0; i < stacks.length; i++) { - StackTraceElement ste = stacks[i]; - StringBuffer sb = new StringBuffer(); - sb.append(ste.getClassName()).append(".").append(ste.getMethodName()).append("(") - .append(ste.getFileName()).append(":").append(ste.getLineNumber()).append(")"); - arr[i] = sb.toString(); - } - this.put((K) EXCEPTION_STACKS, (V) arr); - } - } - - public synchronized void addElapsedTime(String actionName, Long milliSeconds) { - List> elapsedTimes = (List>) this.get(ELAPSED_TIMES); - if (elapsedTimes == null) { - elapsedTimes = new ArrayList>(); - this.put((K) ELAPSED_TIMES, (V) elapsedTimes); - } - Map record = new HashMap<>(); - record.put(actionName, milliSeconds); - elapsedTimes.add(record); - } - - public V getElapsedTimes() { - return this.get(ELAPSED_TIMES); - } - - private Map getStepRequest(String stepName, String requestName) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return null; - } - Map> requests = (Map>) stepResponse.getRequests(); - if (requests == null) { - requests = new HashMap<>(); - stepResponse.setRequests(requests); - requests.put(requestName, new HashMap()); - }else if(!requests.containsKey(requestName)) { - requests.put(requestName, new HashMap()); - } - return (Map) requests.get(requestName); - } - - /** - * 设置Step里调用接口的请求头 - * - * @param stepName - * @param requestName - * @param headerName - * @param headerValue - */ - public void setStepReqHeader(String stepName, String requestName, String headerName, Object headerValue) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - Map req = (Map) request.get("request"); - if (req == null) { - req = new HashMap<>(); - request.put("request", req); - } - Map headers = (Map) req.get("headers"); - if (headers == null) { - headers = new HashMap<>(); - req.put("headers", headers); - } - if (headerName == null || "".equals(headerName)) { - return; - } - headers.put(headerName.toUpperCase(), headerValue); - } - - /** - * 获取Step里调用接口的请求头 - * - * @param stepName - * @param requestName - * @param headerName - */ - public Object getStepReqHeader(String stepName, String requestName, String headerName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map req = (Map) request.get("request"); - if (req == null) { - return null; - } - Map headers = (Map) req.get("headers"); - if (headers == null) { - return null; - } - if (headerName == null || "".equals(headerName)) { - return null; - } - return headers.get(headerName.toUpperCase()); - } - - /** - * 设置Step里调用接口的请求body - * - * @param stepName - * @param requestName - * @param key - * @param value - */ - public void setStepReqBody(String stepName, String requestName, String key, Object value) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - Map req = (Map) request.get("request"); - if (req == null) { - req = new HashMap<>(); - request.put("request", req); - } - if (req.get("body") != null && !(req.get("body") instanceof Map)) { - return; - } - Map body = (Map) req.get("body"); - if (body == null) { - body = new HashMap<>(); - req.put("body", body); - } - body.put(key, value); - } - - /** - * 获取Step里调用接口的请求body - * - * @param stepName - * @param requestName - * @param fieldName - */ - public Object getStepReqBody(String stepName, String requestName, String fieldName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map req = (Map) request.get("request"); - if (req == null) { - req = new HashMap<>(); - request.put("request", req); - } - if (req.get("body") != null && !(req.get("body") instanceof Map)) { - return null; - } - Map body = (Map) req.get("body"); - if (body == null) { - return null; - } - return body.get(fieldName); - } - - /** - * 获取Step里调用接口的请求body - * - * @param stepName - * @param requestName - */ - public Object getStepReqBody(String stepName, String requestName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map req = (Map) request.get("request"); - if (req == null) { - req = new HashMap<>(); - request.put("request", req); - } - return req.get("body"); - } - - /** - * 获取Step里调用的接口的URL参数 - * @param stepName 步骤名【必填】 - * @param requestName 请求的接口名 【必填】 - * @param paramName URL参数名 【选填】,不传时返回所有URL参数 - */ - public Object getStepReqParam(String stepName, String requestName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map req = (Map) request.get("request"); - if (req == null) { - req = new HashMap<>(); - request.put("request", req); - } - return req.get("params"); - } - - /** - * 获取Step里调用的接口的URL参数 - * @param stepName 步骤名【必填】 - * @param requestName 请求的接口名 【必填】 - * @param paramName URL参数名 【必填】 - */ - public Object getStepReqParam(String stepName, String requestName, String paramName) { - Map params = (Map) this.getStepReqParam(stepName, requestName); - return params == null ? null : params.get(paramName); - } - /** - * 设置Step里调用接口响应头 - * - * @param stepName - * @param requestName - * @param headerName - * @param headerValue - */ - public void setStepRespHeader(String stepName, String requestName, String headerName, Object headerValue) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - Map response = (Map) request.get("response"); - if (response == null) { - response = new HashMap<>(); - request.put("response", response); - } - Map headers = (Map) response.get("headers"); - if (headers == null) { - headers = new HashMap<>(); - response.put("headers", headers); - } - if (headerName == null || "".equals(headerName)) { - return; - } - headers.put(headerName.toUpperCase(), headerValue); - } - - /** - * 获取Step里调用接口响应头 - * - * @param stepName - * @param requestName - * @param headerName - */ - public Object getStepRespHeader(String stepName, String requestName, String headerName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map response = (Map) request.get("response"); - if (response == null) { - return null; - } - Map headers = (Map) response.get("headers"); - if (headers == null) { - return null; - } - if (headerName == null || "".equals(headerName)) { - return null; - } - return headers.get(headerName.toUpperCase()); - } - - /** - * 设置Step里调用接口的响应body - * - * @param stepName - * @param requestName - * @param key - * @param value - */ - public void setStepRespBody(String stepName, String requestName, String key, Object value) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - Map response = (Map) request.get("response"); - if (response == null) { - response = new HashMap<>(); - request.put("response", response); - } - if (response.get("body") != null && !(response.get("body") instanceof Map)) { - return; - } - Map body = (Map) response.get("body"); - if (body == null) { - body = new HashMap<>(); - response.put("body", body); - } - body.put(key, value); - } - - /** - * 获取Step里调用接口的响应body - * - * @param stepName - * @param requestName - * @param key - */ - public Object getStepRespBody(String stepName, String requestName, String key) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map response = (Map) request.get("response"); - if (response == null) { - return null; - } - if (response.get("body") != null && !(response.get("body") instanceof Map)) { - return null; - } - Map body = (Map) response.get("body"); - if (body == null) { - return null; - } - return body.get(key); - } - - /** - * 获取Step里调用接口的响应body - * - * @param stepName - * @param requestName - */ - public Object getStepRespBody(String stepName, String requestName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - Map response = (Map) request.get("response"); - if (response == null) { - return null; - } - return response.get("body"); - } - - /** - * 设置Step的结果 - * - * @param stepName - * @param key - * @param value - */ - public void setStepResult(String stepName, String key, Object value) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return; - } - Map result = (Map) stepResponse.getResult(); - if (result == null) { - result = new HashMap<>(); - stepResponse.setResult(result); - } - result.put(key, value); - } - - /** - * 获取Step的结果 - * - * @param stepName - * @param key - */ - public Object getStepResult(String stepName, String key) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return null; - } - Map result = (Map) stepResponse.getResult(); - if (result == null) { - return null; - } - return result.get(key); - } - - /** - * 获取Step的结果 - * - * @param stepName - */ - public Object getStepResult(String stepName) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return null; - } - return stepResponse.getResult(); - } - - /** - * 设置聚合接口的响应头 - * - * @param headerName - * @param headerValue - */ - public void setInputRespHeader(String headerName, Object headerValue) { - Map input = (Map) this.get("input"); - if (input == null) { - return; - } - Map response = (Map) input.get("response"); - if (response == null) { - return; - } - Map headers = (Map) response.get("headers"); - if (headers == null) { - headers = new HashMap<>(); - response.put("headers", headers); - } - headers.put(headerName, headerValue); - } - - /** - * 获取聚合接口的响应头 - * - * @param headerName - */ - public Object getInputRespHeader(String headerName) { - Map input = (Map) this.get("input"); - if (input == null) { - return null; - } - Map response = (Map) input.get("response"); - if (response == null) { - return null; - } - Map headers = (Map) response.get("headers"); - if (headers == null) { - return null; - } - return headers.get(headerName); - } - - /** - * 获取聚合接口的请求头 - * - * @param headerName - */ - public Object getInputReqHeader(String headerName) { - if (headerName == null || "".equals(headerName)) { - return null; - } - Map input = (Map) this.get("input"); - if (input == null) { - return null; - } - Map request = (Map) input.get("request"); - if (request == null) { - return null; - } - Map headers = (Map) request.get("headers"); - if (headers == null) { - return null; - } - return headers.get(headerName.toUpperCase()); - } - - /** - * 设置聚合接口的响应body - * - * @param fieldName - * @param value - */ - public void setInputRespBody(String fieldName, Object value) { - Map input = (Map) this.get("input"); - if (input == null) { - return; - } - Map response = (Map) input.get("response"); - if (response == null) { - response = new HashMap<>(); - input.put("response", response); - } - if (response.get("body") != null && !(response.get("body") instanceof Map)) { - return; - } - Map body = (Map) response.get("body"); - if (body == null) { - body = new HashMap<>(); - response.put("body", body); - } - body.put(fieldName, value); - } - - /** - * 获取聚合接口的响应body - * - * @param fieldName - */ - public Object getInputRespBody(String fieldName) { - Map input = (Map) this.get("input"); - if (input == null) { - return null; - } - Map response = (Map) input.get("response"); - if (response == null) { - return null; - } - if (response.get("body") != null && !(response.get("body") instanceof Map)) { - return null; - } - Map body = (Map) response.get("body"); - if (body == null) { - return null; - } - return body.get(fieldName); - } - - /** - * 获取聚合接口的响应body - * - */ - public Object getInputRespBody() { - Map input = (Map) this.get("input"); - if (input == null) { - return null; - } - Map response = (Map) input.get("response"); - if (response == null) { - return null; - } - return response.get("body"); - } - - /** - * 获取聚合接口的请求body - * - * @param fieldName - */ - @SuppressWarnings("unused") - public Object getInputReqBody(String fieldName) { - Object respBody = getInputReqAttr("body"); - if (respBody != null && !(respBody instanceof Map)) { - return null; - } - Map body = (Map) respBody; - if (body == null) { - return null; - } - return body.get(fieldName); - } - - /** - * 获取聚合接口的请求body - * - */ - public Object getInputReqBody() { - return getInputReqAttr("body"); - } - - /** - * 获取客户端URL请求参数(query string) - */ - public Object getInputReqParam() { - return this.getInputReqAttr("params"); - } - - /** - * 获取客户端URL请求参数(query string) - * @param paramName URL参数名 - */ - public Object getInputReqParam(String paramName) { - Map params = (Map) this.getInputReqAttr("params"); - return params == null ? null : paramName == null ? params : params.get(paramName); - } - - /** - * 获取聚合接口请求属性
- * 可选属性:path,method,headers,params,body - * - */ - public Object getInputReqAttr(String key) { - Map input = (Map) this.get("input"); - if (input == null) { - return null; - } - Map request = (Map) input.get("request"); - if (request == null) { - return null; - } - return request.get(key); - } - - /** - * 设置Step的循环对象
- * Set the current circle item of step
- *
- * - * @param stepName - * @param item - * @param index - */ - public void setStepCircleItem(String stepName, Object item, Integer index) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return; - } - stepResponse.setItem(item); - stepResponse.setIndex(index); - } - - /** - * 添加Step的循环结果
- * Add the result of current circle item
- *
- * - * @param stepName - * @param key - * @param value - */ - public void addStepCircleResult(String stepName) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return; - } - List> circle = (List>) stepResponse.getCircle(); - if (circle == null) { - circle = new ArrayList<>(); - stepResponse.setCircle(circle); - } - Map circleResult = new HashMap<>(); - circleResult.put("requests", deepCopy(stepResponse.getRequests())); - circleResult.put("result", deepCopy(stepResponse.getResult())); - circleResult.put("item", deepCopy(stepResponse.getItem())); - circleResult.put("index", stepResponse.getIndex()); - circle.add(circleResult); - } - - /** - * 获取Step的循环对象
- * Returns current circle item
- * - * @param stepName - */ - public Object getStepItem(String stepName) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return null; - } - return stepResponse.getItem(); - } - - /** - * 获取Step的循环结果
- * Returns circle result list of step
- * - * @param stepName - */ - public List> getStepCircle(String stepName) { - StepResponse stepResponse = (StepResponse) this.get(stepName); - if (stepResponse == null) { - return null; - } - return stepResponse.getCircle(); - } - - /** - * 设置请求的循环对象
- * Set current circle item of request
- * - * @param stepName - * @param requestName - * @param item - */ - public void setRequestCircleItem(String stepName, String requestName, Object item, Integer index) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - request.put("item", item); - request.put("index", index); - } - - /** - * 设置请求的循环结果
- * Set current circle result of request
- * - * @param stepName - * @param requestName - */ - public void addRequestCircleResult(String stepName, String requestName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - List> circle = (List>) request.get("circle"); - if (circle == null) { - circle = new ArrayList<>(); - request.put("circle", circle); - } - Map circleResult = new HashMap<>(); - circleResult.put("request", deepCopy(request.get("request"))); - circleResult.put("response", deepCopy(request.get("response"))); - circleResult.put("item", deepCopy(request.get("item"))); - circleResult.put("index", request.get("index")); - circle.add(circleResult); - } - - /** - * 设置判断条件组件结果
- * Set result of condition components
- * - * @param stepName step name - * @param requestName request name - * @param conditionDesc condition description, such as:
- * circle[0]-execCondition:my condition 1
- * circle[1]-breakCondition:my condition 2
- * condition:my condition 3
- * @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> results = (List>) stepResponse.getConditionResults(); - if (results == null) { - results = new ArrayList<>(); - stepResponse.setConditionResults(results); - } - Map result = new HashMap<>(); - result.put(conditionDesc, rs); - results.add(result); - } else { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return; - } - List> results = (List>) request.get("conditionResults"); - if (results == null) { - results = new ArrayList<>(); - request.put("conditionResults", results); - } - Map result = new HashMap<>(); - result.put(conditionDesc, rs); - results.add(result); - } - } - - /** - * 获取请求的循环对象
- * Returns the current circle item of request
- * - * @param stepName - * @param requestName - */ - public Object getRequestCircleItem(String stepName, String requestName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - return request.get("item"); - } - - /** - * 获取请求的循环结果
- * Returns circle result list of request
- * - * @param stepName - * @param requestName - */ - public List> getRequestCircle(String stepName, String requestName) { - Map request = getStepRequest(stepName, requestName); - if (request == null) { - return null; - } - return (List>) request.get("circle"); - } - - private Object deepCopy(Object obj) { - if(obj == null) { - return obj; - } - if(obj.getClass().isPrimitive()) { - return obj; - } - return JSON.parse(JSON.toJSONString(obj)); - } - - public ConfigurableApplicationContext getApplicationContext(){ - return this.applicationContext; - } - - public void setApplicationContext(ConfigurableApplicationContext applicationContext) { - this.applicationContext = applicationContext; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/StepResponse.java b/fizz-core/src/main/java/com/fizzgate/fizz/StepResponse.java deleted file mode 100644 index ba32083..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/StepResponse.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @author linwaiwai - */ -public class StepResponse { - private String stepName; - private Map> requests; - private Map result; - private boolean stop; - // circle item - private Object item; - // index of circle item - private Integer index; - // circle results - private List> circle; - // result of condition components - private List> conditionResults; - - public StepResponse(Step aStep, HashMap item, Map> requests) { - setStepName(aStep.getName()); - setResult(item); - setRequests(requests); - } - public StepResponse(Step aStep, HashMap item) { - setStepName(aStep.getName()); - setResult(item); - } - - public void addRequest(String requestName, Map requestObj) { - if (this.requests.containsKey(requestName)) { - this.requests.get(requestName).putAll(requestObj); - } else { - this.requests.put(requestName, requestObj); - } - } - - public boolean isStop() { - return stop; - } - public void setStop(boolean stop) { - this.stop = stop; - } - public String getStepName() { - return stepName; - } - public void setStepName(String stepName) { - this.stepName = stepName; - } - public Map> getRequests() { - return requests; - } - public void setRequests(Map> requests) { - this.requests = requests; - } - public Map getResult() { - return result; - } - public void setResult(Map result) { - this.result = result; - } - public Object getItem() { - return item; - } - public void setItem(Object item) { - this.item = item; - } - public List> getCircle() { - return circle; - } - public void setCircle(List> circle) { - this.circle = circle; - } - public Integer getIndex() { - return index; - } - public void setIndex(Integer index) { - this.index = index; - } - public List> getConditionResults() { - return conditionResults; - } - public void setConditionResults(List> conditionResults) { - this.conditionResults = conditionResults; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentExecutor.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentExecutor.java deleted file mode 100644 index c6ff6e0..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentExecutor.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.component; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.function.BiFunction; - -import org.noear.snack.ONode; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.component.circle.Circle; -import com.fizzgate.fizz.component.condition.Condition; - -import reactor.core.publisher.Mono; - -/** - * Condition component - * - * @author Francis Dong - * - */ -public class ComponentExecutor { - - /** - * Converts step context to ONode - * - * @param stepContext context - * @return - */ - public static ONode toONode(StepContext stepContext) { - ONode o = null; - synchronized (stepContext) { - o = ONode.loadObj(stepContext); - } - return o; - } - - public static List buildComponents(List> componentConfig) { - List components = new ArrayList<>(); - - if (componentConfig != null && componentConfig.size() > 0) { - for (Map m : componentConfig) { - // condition - if (ComponentTypeEnum.CONDITION.getCode().equals(m.get("type"))) { - Condition c = JSON.parseObject(JSON.toJSONString(m), Condition.class); - components.add(c); - } - - // circle - if (ComponentTypeEnum.CIRCLE.getCode().equals(m.get("type"))) { - Circle c = JSON.parseObject(JSON.toJSONString(m), Circle.class); - components.add(c); - } - } - } - - return components; - } - - /** - * - * @param components - * @param stepContext - * @param f - */ - public static Mono exec(List components, StepContext stepContext, - StepContextPosition stepCtxPos, BiFunction f) { - if (components != null && components.size() > 0) { - // conditions before circle component - List conditions = new ArrayList<>(); - Circle circle = null; - for (IComponent component : components) { - if (ComponentTypeEnum.CIRCLE == component.getType()) { - circle = (Circle) component; - } - if (circle == null && ComponentTypeEnum.CONDITION == component.getType()) { - conditions.add((Condition) component); - } - } - - if (conditions != null && conditions.size() > 0) { - ONode ctxNode = toONode(stepContext); - for (Condition c : conditions) { - boolean rs = c.exec(ctxNode); - stepContext.addConditionResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName(), c.getDesc(), - rs); - if (!rs) { - return Mono.just(new ComponentResult()); - } - } - } - - if (circle != null) { - return circle.exec(stepContext, stepCtxPos, f); - } else { - return f.apply(stepContext, stepCtxPos); - } - } - return Mono.just(new ComponentResult()); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentResult.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentResult.java deleted file mode 100644 index ae853f2..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentResult.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.fizzgate.fizz.component; - -public class ComponentResult { - - public ComponentResult() { - - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentTypeEnum.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentTypeEnum.java deleted file mode 100644 index fd33de9..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/ComponentTypeEnum.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.component; - -/** - * Component Type - * - * @author Francis Dong - * - */ -public enum ComponentTypeEnum { - - CONDITION("condition"), CIRCLE("circle"); - - private String code; - - private ComponentTypeEnum(String code) { - this.code = code; - } - - public static ComponentTypeEnum getEnumByCode(String code) { - for (ComponentTypeEnum item : ComponentTypeEnum.values()) { - if (item.getCode().equals(code)) { - return item; - } - } - - return null; - } - - public String getCode() { - return code; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/IComponent.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/IComponent.java deleted file mode 100644 index 39901c8..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/IComponent.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.component; - -/** - * Component interface - * - * @author Francis Dong - * - */ -public interface IComponent { - - /** - * Returns component type - * @return - */ - public ComponentTypeEnum getType(); - - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/OperatorEnum.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/OperatorEnum.java deleted file mode 100644 index 3c4b81e..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/OperatorEnum.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.component; - -/** - * Operator - * - * @author Francis Dong - * - */ -public enum OperatorEnum { - - EQ("eq"), NE("ne"), GT("gt"), GE("ge"), LT("lt"), LE("le"), CONTAINS("contains"), NOTCONTAIN("notContain"), CONTAINSANY("containsAny"), - ISNULL("isNull"), ISNOTNULL("isNotNull"), ISBLANK("isBlank"), ISNOTBLANK("isNotBlank"), ISEMPTY("isEmpty"), - ISNOTEMPTY("isNotEmpty"); - - private String code; - - private OperatorEnum(String code) { - this.code = code; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/StepContextPosition.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/StepContextPosition.java deleted file mode 100644 index 879111c..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/StepContextPosition.java +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.component; - -import lombok.Data; - -/** - * - * @author Francis Dong - * - */ -@Data -public class StepContextPosition { - - private String stepName; - private String requestName; - - public StepContextPosition(String stepName) { - this.stepName = stepName; - } - - public StepContextPosition(String stepName, String requestName) { - this.stepName = stepName; - this.requestName = requestName; - } - - public String getPath() { - if (this.requestName == null) { - return this.stepName; - } - return this.stepName + ".requests." + this.requestName; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/circle/Circle.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/circle/Circle.java deleted file mode 100644 index 8382d56..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/circle/Circle.java +++ /dev/null @@ -1,337 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.component.circle; - -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.function.BiFunction; - -import org.noear.snack.ONode; - -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.component.ComponentExecutor; -import com.fizzgate.fizz.component.ComponentResult; -import com.fizzgate.fizz.component.ComponentTypeEnum; -import com.fizzgate.fizz.component.IComponent; -import com.fizzgate.fizz.component.StepContextPosition; -import com.fizzgate.fizz.component.condition.Condition; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.field.ValueTypeEnum; -import com.fizzgate.fizz.input.PathMapping; - -import lombok.Data; -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - -/** - * Circle component - * - * @author Francis Dong - * - */ -public class Circle implements IComponent { - - private static final String type = ComponentTypeEnum.CIRCLE.getCode(); - - private String desc; - - private ValueTypeEnum dataSourceType; - - private Object dataSource; - - private List execConditions; - - private List breakConditions; - - @Override - public ComponentTypeEnum getType() { - return ComponentTypeEnum.getEnumByCode(type); - } - - /** - * - * @param desc [optional] description - * @param dataSourceType [required] type of data source - * @param dataSource [required] data source - * @param execConditions [optional] conditions to execute current circle loop - * item - * @param breakConditions [optional] conditions to break circle - */ - public Circle(String desc, ValueTypeEnum dataSourceType, Object dataSource, List execConditions, - List breakConditions) { - this.desc = desc; - this.dataSourceType = dataSourceType; - this.dataSource = dataSource; - this.execConditions = execConditions; - this.breakConditions = breakConditions; - } - - /** - * Current item - */ - private Object currentItem; - - /** - * Index of current item - */ - private Integer index; - - /** - * Fixed value of dataSource - */ - private Integer fixedValue; - - /** - * Reference value of dataSource - */ - private Object refValue; - - private boolean refReadFlag; - - private Integer getFixedValue(ONode ctxNode) { - if (fixedValue != null) { - return fixedValue; - } - if (dataSource == null) { - return fixedValue; - } - if (dataSource instanceof Integer || dataSource instanceof Long || dataSource instanceof String) { - 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) { - throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer"); - } - return fixedValue; - } else { - throw new FizzRuntimeException("invalid data source, fixed data source must be a positive integer"); - } - } - - @SuppressWarnings("unchecked") - private Object getRefValue(ONode ctxNode) { - if (refReadFlag) { - return refValue; - } - Object value = PathMapping.getValueByPath(ctxNode, (String) dataSource); - if (value == null) { - return null; - } - if (value instanceof Collection) { - refValue = (List) value; - 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 { - throw new FizzRuntimeException( - "invalid data source, referenced data source must be a positive integer or an array"); - } - } - - /** - * Returns next circle item, returns null if no item left or dataSource is null - * - * @return - */ - @SuppressWarnings("unchecked") - public CircleItem next(ONode ctxNode) { - if (ValueTypeEnum.FIXED.equals(dataSourceType)) { - Integer total = this.getFixedValue(ctxNode); - 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; - } - } else if (ValueTypeEnum.REF.equals(dataSourceType)) { - Object refValue = this.getRefValue(ctxNode); - if (refValue instanceof Collection) { - List list = (List) refValue; - if (index == null) { - index = 0; - currentItem = list.get(index); - return new CircleItem(currentItem, index); - } else if (index.intValue() < list.size() - 1) { - index = index + 1; - currentItem = list.get(index); - 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; - } - - /** - * Returns true if execConditions are all true, false otherwise - * - * @param ctxNode - * @return - */ - public boolean canExec(int index, ONode ctxNode, StepContext stepContext, - StepContextPosition stepCtxPos) { - if (this.execConditions != null && this.execConditions.size() > 0) { - try { - for (Condition c : execConditions) { - boolean rs = c.exec(ctxNode); - stepContext.addConditionResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName(), - "circle[" + index + "]-execCondition:" + c.getDesc(), rs); - if (!rs) { - return false; - } - } - } catch (FizzRuntimeException e) { - throw new FizzRuntimeException(type + " " + e.getMessage(), e.getCause()); - } - } - return true; - } - - /** - * Returns true if breakConditions are all true, false otherwise - * - * @param ctxNode - * @return - */ - public boolean breakCircle(int index, ONode ctxNode, StepContext stepContext, - StepContextPosition stepCtxPos) { - if (this.breakConditions != null && this.breakConditions.size() > 0) { - try { - for (Condition c : breakConditions) { - boolean rs = c.exec(ctxNode); - stepContext.addConditionResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName(), - "circle[" + index + "]-breakCondition:" + c.getDesc(), rs); - if (rs) { - return true; - } - } - } catch (FizzRuntimeException e) { - throw new FizzRuntimeException(type + " " + e.getMessage(), e.getCause()); - } - } - return false; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public Mono exec(StepContext stepContext, StepContextPosition stepCtxPos, - BiFunction f) { - ONode ctxNode1 = ComponentExecutor.toONode(stepContext); - CircleItem nextItem = this.next(ctxNode1); - if (nextItem != null) { - return Mono.just(new CircleItemResult(ctxNode1, nextItem, null)).expand(circleItemResult -> { - // put nextItem to step context - CircleItem cItem = circleItemResult.nextItem; - if (stepCtxPos.getRequestName() != null) { - stepContext.setRequestCircleItem(stepCtxPos.getStepName(), stepCtxPos.getRequestName(), - cItem.getItem(), cItem.getIndex()); - } else { - 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() + ".index", cItem.getIndex(), true); - - if (!this.canExec(cItem.getIndex(), ctxNode, stepContext, stepCtxPos)) { - CircleItem nextItem2 = this.next(ctxNode); - if (nextItem2 == null) { - return Mono.empty(); - } - return Mono.just(new CircleItemResult(ctxNode, nextItem2, null)); - } - return f.apply(stepContext, stepCtxPos).flatMap(r -> { - if (stepCtxPos.getRequestName() != null) { - stepContext.addRequestCircleResult(stepCtxPos.getStepName(), stepCtxPos.getRequestName()); - } else { - stepContext.addStepCircleResult(stepCtxPos.getStepName()); - } - ONode ctxNode2 = ComponentExecutor.toONode(stepContext); - if (this.breakCircle(cItem.getIndex(), ctxNode2, stepContext, stepCtxPos)) { - return Mono.empty(); - } - CircleItem nextItem2 = this.next(ctxNode2); - if (nextItem2 == null) { - return Mono.empty(); - } - return Mono.just(new CircleItemResult(ctxNode2, nextItem2, r)); - }); - }).flatMap(circleItemResult -> Flux.just(circleItemResult)).collectList().flatMap(r -> { - List list = (List) r; - if (list != null && list.size() > 0) { - Collections.reverse(list); - for (int i = 0; i < list.size(); i++) { - if (list.get(i).result != null) { - return Mono.just(list.get(i).result); - } - } - } - return Mono.just(new ComponentResult()); - }); - } else { - return Mono.just(new ComponentResult()); - } - } - - @Data - class CircleItemResult { - private ONode ctxNode; - private CircleItem nextItem; - private Object result; - - public CircleItemResult(ONode ctxNode, CircleItem nextItem, Object result) { - this.ctxNode = ctxNode; - this.nextItem = nextItem; - this.result = result; - } - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/circle/CircleItem.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/circle/CircleItem.java deleted file mode 100644 index a1d25c4..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/circle/CircleItem.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.component.circle; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * - * @author Francis Dong - * - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class CircleItem { - - private Object item; - - private Integer index; - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/condition/Condition.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/condition/Condition.java deleted file mode 100644 index e09ceb1..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/condition/Condition.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.component.condition; - -import java.util.Collection; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.CollectionUtils; -import org.springframework.util.ObjectUtils; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.fizz.component.ComponentTypeEnum; -import com.fizzgate.fizz.component.IComponent; -import com.fizzgate.fizz.component.OperatorEnum; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.field.RefDataTypeEnum; -import com.fizzgate.fizz.field.ValueTypeEnum; -import com.fizzgate.fizz.input.PathMapping; -import com.fizzgate.fizz.input.extension.request.RequestInput; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Condition component - * - * @author Francis Dong - * - */ -@Data -public class Condition implements IComponent { - - private static final Logger LOGGER = LoggerFactory.getLogger(Condition.class); - - private static final String type = ComponentTypeEnum.CONDITION.getCode(); - - private String desc; - - private ConditionValue value1; - - private OperatorEnum operator; - - private ConditionValue value2; - - public Condition(String desc, ConditionValue value1, OperatorEnum operator, ConditionValue value2) { - this.desc = desc; - this.value1 = value1; - this.operator = operator; - this.value2 = value2; - } - - @Override - public ComponentTypeEnum getType() { - return ComponentTypeEnum.getEnumByCode(type); - } - - /** - * Execute condition - * - * @return - */ - @SuppressWarnings({ "rawtypes" }) - public boolean exec(ONode ctxNode) { - if (value1 == null || operator == null) { - return false; - } - - boolean rs = false; - try { - Object v1 = null; - if (ValueTypeEnum.FIXED.equals(value1.getType())) { - v1 = value1.getValue(); - } else { - v1 = PathMapping.getValueByPath(ctxNode, (String) value1.getValue()); - v1 = this.cast(value1.getRefDataType(), v1); - } - - Object v2 = null; - if (value2 != null && value2.getType() != null) { - if (ValueTypeEnum.FIXED.equals(value2.getType())) { - v2 = value2.getValue(); - } else { - v2 = PathMapping.getValueByPath(ctxNode, (String) value2.getValue()); - v2 = this.cast(value2.getRefDataType(), v2); - } - } - - switch (operator) { - case EQ: - if (v1 == null && v2 == null) { - rs = true; - } else if (v1 != null && v2 != null) { - rs = this.compare(v1, v2) == 0; - } - break; - case NE: - if (v1 == null && v2 == null) { - rs = false; - } else if ((v1 == null && v2 != null) || (v1 != null && v2 == null)) { - rs = true; - } else if (v1 != null && v2 != null) { - rs = this.compare(v1, v2) != 0; - } - break; - case GT: - rs = this.compare(v1, v2) > 0; - break; - case GE: - rs = this.compare(v1, v2) >= 0; - break; - case LT: - rs = this.compare(v1, v2) < 0; - break; - case LE: - rs = this.compare(v1, v2) <= 0; - break; - case CONTAINS: - if (v1 == null) { - rs = false; - break; - } - if (v1 instanceof Collection && !(v2 instanceof Collection)) { - Collection coll1 = (Collection) v1; - if (v2 instanceof Integer || v2 instanceof Long) { - Long el = Long.valueOf(v2.toString()); - rs = containsLong(coll1, el); - } else if (v2 instanceof Float || v2 instanceof Double) { - Double el = Double.valueOf(v2.toString()); - rs = containsDouble(coll1, el); - } else { - rs = CollectionUtils.contains(coll1.iterator(), v2); - } - } else if (!(v1 instanceof Collection)) { - throw new FizzRuntimeException("value1 must be a collection"); - } else if (v2 instanceof Collection) { - throw new FizzRuntimeException("value2 can not be a collection"); - } - break; - case NOTCONTAIN: - if (v1 == null) { - rs = true; - break; - } - if (v1 instanceof Collection && !(v2 instanceof Collection)) { - Collection coll1 = (Collection) v1; - if (v2 instanceof Integer || v2 instanceof Long) { - Long el = Long.valueOf(v2.toString()); - rs = !containsLong(coll1, el); - } else if (v2 instanceof Float || v2 instanceof Double) { - Double el = Double.valueOf(v2.toString()); - rs = !containsDouble(coll1, el); - } else { - rs = !CollectionUtils.contains(coll1.iterator(), v2); - } - } else if (!(v1 instanceof Collection)) { - throw new FizzRuntimeException("value1 must be a collection"); - } else if (v2 instanceof Collection) { - throw new FizzRuntimeException("value2 can not be a collection"); - } - break; - case CONTAINSANY: - if (v1 == null || v2 == null) { - rs = false; - break; - } - if (v1 instanceof Collection && v2 instanceof Collection) { - Collection coll1 = (Collection) v1; - Collection coll2 = (Collection) v2; - rs = CollectionUtils.containsAny(coll1, coll2); - } else if (!(v1 instanceof Collection)) { - throw new FizzRuntimeException("value1 must be a collection"); - } else if (!(v2 instanceof Collection)) { - throw new FizzRuntimeException("value2 must be a collection"); - } - break; - case ISNULL: - rs = v1 == null; - break; - case ISNOTNULL: - rs = v1 != null; - break; - case ISBLANK: - rs = v1 == null || StringUtils.isBlank(v1.toString()); - break; - case ISNOTBLANK: - rs = v1 != null && StringUtils.isNotBlank(v1.toString()); - break; - case ISEMPTY: - rs = v1 == null || (v1 instanceof Collection && ((Collection) v1).isEmpty()) - || (v1 instanceof Map && ((Map) v1).isEmpty()); - break; - case ISNOTEMPTY: - if (v1 != null) { - if (v1 instanceof Collection) { - rs = !((Collection) v1).isEmpty(); - } else if (v1 instanceof Map) { - rs = !((Map) v1).isEmpty(); - } - } - break; - default: - break; - } - } catch (FizzRuntimeException e) { - String message = type + ": " + e.getMessage() + ", data=" + JSON.toJSONString(this); - LOGGER.error(message, e); - throw new FizzRuntimeException(message, e.getCause()); - } - - return rs; - } - - @SuppressWarnings("rawtypes") - private int compare(Object v1, Object v2) { - if (v1 == null || v2 == null) { - throw new FizzRuntimeException("value1 and value2 can not be null"); - } - if (v1 instanceof Boolean && v2 instanceof Boolean) { - Boolean n1 = (Boolean) v1; - Boolean n2 = (Boolean) v2; - return n1.compareTo(n2); - } else if ((v1 instanceof Integer || v1 instanceof Long || v1 instanceof Float || v1 instanceof Double) - && (v2 instanceof Integer || v2 instanceof Long || v2 instanceof Float || v2 instanceof Double)) { - // compare value if both are numbers - Double n1 = Double.valueOf(v1.toString()); - Double n2 = Double.valueOf(v2.toString()); - return n1.compareTo(n2); - } else if (v1 instanceof String && v2 instanceof String) { - String s1 = v1.toString(); - String s2 = v2.toString(); - return s1.compareTo(s2); - } else { - throw new FizzRuntimeException( - "types of value1 and value2 are not consistent or not supported for comparision"); - } - } - - private Object cast(RefDataTypeEnum type, Object val) { - if (type != null && val != null) { - switch (type) { - case INT: - val = Integer.valueOf(val.toString()); - break; - case LONG: - val = Long.valueOf(val.toString()); - break; - case FLOAT: - val = Float.valueOf(val.toString()); - break; - case DOUBLE: - val = Double.valueOf(val.toString()); - break; - case BOOLEAN: - val = Boolean.valueOf(val.toString()); - break; - case STRING: - val = val.toString(); - break; - } - } - return val; - } - - @SuppressWarnings("rawtypes") - private boolean containsLong(Collection coll, Long el) { - if (CollectionUtils.isEmpty(coll)) { - return false; - } - - for (Object obj : coll) { - Long obj2 = null; - if (obj instanceof Integer) { - obj2 = Long.valueOf(obj.toString()); - } - if (ObjectUtils.nullSafeEquals(obj2, el)) { - return true; - } - } - - return false; - } - - @SuppressWarnings("rawtypes") - private boolean containsDouble(Collection coll, Double el) { - if (CollectionUtils.isEmpty(coll)) { - return false; - } - - for (Object obj : coll) { - Double obj2 = null; - if (obj instanceof Float) { - obj2 = Double.valueOf(obj.toString()); - } - if (ObjectUtils.nullSafeEquals(obj2, el)) { - return true; - } - } - - return false; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/component/condition/ConditionValue.java b/fizz-core/src/main/java/com/fizzgate/fizz/component/condition/ConditionValue.java deleted file mode 100644 index 5414547..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/component/condition/ConditionValue.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.component.condition; - -import com.fizzgate.fizz.field.FixedDataTypeEnum; -import com.fizzgate.fizz.field.RefDataTypeEnum; -import com.fizzgate.fizz.field.ValueTypeEnum; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Condition value - * - * @author Francis Dong - * - */ -@Data -@AllArgsConstructor -@NoArgsConstructor -public class ConditionValue { - - private ValueTypeEnum type; - - private FixedDataTypeEnum fixedDataType; - - private RefDataTypeEnum refDataType; - - private Object value; - - public ConditionValue(ValueTypeEnum type, FixedDataTypeEnum fixedDataType, Object value) { - this.type = type; - this.fixedDataType = fixedDataType; - this.value = value; - } - - public ConditionValue(ValueTypeEnum type, RefDataTypeEnum refDataType, Object value) { - this.type = type; - this.refDataType = refDataType; - this.value = value; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/exception/FizzRuntimeException.java b/fizz-core/src/main/java/com/fizzgate/fizz/exception/FizzRuntimeException.java deleted file mode 100644 index c3e5138..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/exception/FizzRuntimeException.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.exception; - -import com.fizzgate.fizz.StepContext; - -public class FizzRuntimeException extends RuntimeException { - - private StepContext stepContext; - - public FizzRuntimeException(String message) { - super(message); - } - - public FizzRuntimeException(String message, Throwable cause) { - super(message, cause); - this.setStackTrace(cause.getStackTrace()); - } - - public FizzRuntimeException(String message, StepContext stepContext) { - super(message); - this.stepContext = stepContext; - } - - public FizzRuntimeException(String message, Throwable cause, StepContext stepContext) { - super(message, cause); - this.setStackTrace(cause.getStackTrace()); - this.stepContext = stepContext; - } - - public StepContext getStepContext() { - return stepContext; - } - - public void setStepContext(StepContext stepContext) { - this.stepContext = stepContext; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/field/FieldConfig.java b/fizz-core/src/main/java/com/fizzgate/fizz/field/FieldConfig.java deleted file mode 100644 index b1b736d..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/field/FieldConfig.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.field; - -import java.util.Map; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * - * @author Francis Dong - * - */ -@Data -@NoArgsConstructor -@AllArgsConstructor -public class FieldConfig { - - private ValueTypeEnum type; - - private FixedDataTypeEnum fixedDataType; - - private RefDataTypeEnum refDataType; - - private Object value; - - public FieldConfig(Map configMap) { - if (configMap != null && !configMap.isEmpty()) { - if (configMap.containsKey("type")) { - this.type = ValueTypeEnum.getEnumByCode(configMap.get("type").toString()); - } - if (configMap.containsKey("fixedDataType")) { - this.fixedDataType = FixedDataTypeEnum.getEnumByCode(configMap.get("fixedDataType").toString()); - } - if (configMap.containsKey("refDataType")) { - this.refDataType = RefDataTypeEnum.getEnumByCode(configMap.get("refDataType").toString()); - } - if (configMap.containsKey("value")) { - this.value = configMap.get("value"); - } - } - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/field/FixedDataTypeEnum.java b/fizz-core/src/main/java/com/fizzgate/fizz/field/FixedDataTypeEnum.java deleted file mode 100644 index 4a3b10e..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/field/FixedDataTypeEnum.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.field; - -/** - * Data type of fixed value - * - * @author Francis Dong - * - */ -public enum FixedDataTypeEnum{ - - NUMBER("number"), STRING("string"), BOOLEAN("boolean"); - - private String code; - - private FixedDataTypeEnum(String code) { - this.code = code; - } - - public String getCode() { - return this.code; - } - - public void setCode(String code) { - this.code = code; - } - - public static FixedDataTypeEnum getEnumByCode(String code) { - for (FixedDataTypeEnum e : FixedDataTypeEnum.values()) { - if (e.getCode().equals(code)) { - return e; - } - } - return null; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/field/RefDataTypeEnum.java b/fizz-core/src/main/java/com/fizzgate/fizz/field/RefDataTypeEnum.java deleted file mode 100644 index ca926a3..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/field/RefDataTypeEnum.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.field; - -/** - * Data type of reference value - * - * @author Francis Dong - * - */ -public enum RefDataTypeEnum { - - INT("int"), LONG("long"), FLOAT("float"), DOUBLE("double"), STRING("string"), BOOLEAN("boolean"), ARRAY("array"); - - private String code; - - private RefDataTypeEnum(String code) { - this.code = code; - } - - public String getCode() { - return this.code; - } - - public void setCode(String code) { - this.code = code; - } - - public static RefDataTypeEnum getEnumByCode(String code) { - for (RefDataTypeEnum e : RefDataTypeEnum.values()) { - if (e.getCode().equals(code)) { - return e; - } - } - return null; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/field/ValueTypeEnum.java b/fizz-core/src/main/java/com/fizzgate/fizz/field/ValueTypeEnum.java deleted file mode 100644 index fab8b64..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/field/ValueTypeEnum.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.field; - -/** - * Value Type - * - * @author Francis Dong - * - */ -public enum ValueTypeEnum { - - FIXED("fixed"), REF("ref"), FUNC("func"); - - private String code; - - private ValueTypeEnum(String code) { - this.code = code; - } - - public String getCode() { - return code; - } - - public static ValueTypeEnum getEnumByCode(String code) { - for (ValueTypeEnum e : ValueTypeEnum.values()) { - if (e.getCode().equals(code)) { - return e; - } - } - return null; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/CodecFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/CodecFunc.java deleted file mode 100644 index 23553cc..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/CodecFunc.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.function; - -import java.io.UnsupportedEncodingException; -import java.security.Key; -import java.util.Base64; - -import javax.crypto.Cipher; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.DESKeySpec; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -import org.apache.commons.codec.digest.HmacAlgorithms; -import org.apache.commons.codec.digest.HmacUtils; -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fizzgate.util.DigestUtils; - -/** - * Codec Functions - * - * @author Francis Dong - * - */ -public class CodecFunc implements IFunc { - - private static final Logger LOGGER = LoggerFactory.getLogger(CodecFunc.class); - - private static final String CHARSET_UTF8 = "UTF-8"; - - private static final String IV = "12345678"; - - private static CodecFunc singleton; - - public static CodecFunc getInstance() { - if (singleton == null) { - synchronized (CodecFunc.class) { - if (singleton == null) { - CodecFunc instance = new CodecFunc(); - instance.init(); - singleton = instance; - } - } - } - return singleton; - } - - private CodecFunc() { - } - - public void init() { - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.md5", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.sha1", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.sha256", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.sha384", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.sha512", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.base64Encode", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.base64Decode", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.aesEncrypt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.aesDecrypt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.desEncrypt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.desDecrypt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.hmacMd5", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.hmacSha1", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.hmacSha224", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.hmacSha256", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.hmacSha384", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "codec.hmacSha512", this); - } - - public String md5(String data) { - return DigestUtils.md5Hex(data); - } - - public String sha1(String data) { - return DigestUtils.sha1Hex(data); - } - - public String sha256(String data) { - return DigestUtils.sha256Hex(data); - } - - public String sha384(String data) { - return DigestUtils.sha384Hex(data); - } - - public String sha512(String data) { - return DigestUtils.sha512Hex(data); - } - - public String base64Encode(String data) throws Exception { - try { - return Base64.getEncoder().encodeToString(data.getBytes(CHARSET_UTF8)); - } catch (UnsupportedEncodingException e) { - LOGGER.error("Base64 encode error, data={}", data, e); - throw e; - } - } - - public String base64Decode(String data) throws Exception { - return new String(Base64.getDecoder().decode(data)); - } - - public String aesEncrypt(String data, String key) throws Exception { - if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) { - return null; - } - try { - Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); - SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_UTF8), "AES"); - cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); - byte[] result = cipher.doFinal(data.getBytes(CHARSET_UTF8)); - return Base64.getEncoder().encodeToString(result); - } catch (Exception e) { - LOGGER.error("AES encrypt error, data={}", data, e); - throw e; - } - } - - public String aesDecrypt(String data, String key) throws Exception { - if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) { - return null; - } - try { - Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); - SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(CHARSET_UTF8), "AES"); - cipher.init(Cipher.DECRYPT_MODE, secretKeySpec); - byte[] result = Base64.getDecoder().decode(data); - return new String(cipher.doFinal(result)); - } catch (Exception e) { - LOGGER.error("AES decrypt error, data={}", data, e); - throw e; - } - } - - public String desEncrypt(String data, String key) throws Exception { - if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) { - return null; - } - try { - DESKeySpec dks = new DESKeySpec(key.getBytes(CHARSET_UTF8)); - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - Key secretKey = keyFactory.generateSecret(dks); - Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); - IvParameterSpec iv = new IvParameterSpec(IV.getBytes(CHARSET_UTF8)); - cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); - byte[] bytes = cipher.doFinal(data.getBytes(CHARSET_UTF8)); - return new String(Base64.getEncoder().encode(bytes)); - } catch (Exception e) { - LOGGER.error("DES eecrypt error, data={}", data, e); - throw e; - } - } - - public String desDecrypt(String data, String key) throws Exception { - if (StringUtils.isBlank(data) || StringUtils.isBlank(key)) { - return null; - } - try { - DESKeySpec dks = new DESKeySpec(key.getBytes(CHARSET_UTF8)); - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); - Key secretKey = keyFactory.generateSecret(dks); - Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); - IvParameterSpec iv = new IvParameterSpec(IV.getBytes(CHARSET_UTF8)); - cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); - return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET_UTF8))), CHARSET_UTF8); - } catch (Exception e) { - LOGGER.error("DES decrypt error, data={}", data, e); - throw e; - } - } - - public String hmacMd5(String data, String secretKey) { - return new HmacUtils(HmacAlgorithms.HMAC_MD5, secretKey).hmacHex(data); - } - - public String hmacSha1(String data, String secretKey) { - return new HmacUtils(HmacAlgorithms.HMAC_SHA_1, secretKey).hmacHex(data); - } - - public String hmacSha224(String data, String secretKey) { - return new HmacUtils(HmacAlgorithms.HMAC_SHA_224, secretKey).hmacHex(data); - } - - public String hmacSha256(String data, String secretKey) { - return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, secretKey).hmacHex(data); - } - - public String hmacSha384(String data, String secretKey) { - return new HmacUtils(HmacAlgorithms.HMAC_SHA_384, secretKey).hmacHex(data); - } - - public String hmacSha512(String data, String secretKey) { - return new HmacUtils(HmacAlgorithms.HMAC_SHA_512, secretKey).hmacHex(data); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/CommonFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/CommonFunc.java deleted file mode 100644 index 9b59ffc..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/CommonFunc.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.function; - -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Common Functions - * - * @author Francis Dong - * - */ -public class CommonFunc implements IFunc { - - private static final Logger LOGGER = LoggerFactory.getLogger(CommonFunc.class); - - private static CommonFunc singleton; - - public static CommonFunc getInstance() { - if (singleton == null) { - synchronized (CommonFunc.class) { - if (singleton == null) { - CommonFunc instance = new CommonFunc(); - instance.init(); - singleton = instance; - } - } - } - return singleton; - } - - private CommonFunc() { - } - - public void init() { - FuncExecutor.register(NAME_SPACE_PREFIX + "common.iif", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.equals", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.isNull", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.isNotNull", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.isBlank", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.isNotBlank", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.isEmpty", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.isNotEmpty", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.and", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.or", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "common.not", this); - } - - /** - * Immediate if function (iif) - * - * @param exprResult the result of expression that is to be evaluated. - * @param truepart defines what the iif function returns if the exprResult is - * true. - * @param falsepart defines what the iif function returns if the exprResult is - * false. - * @return returns the truepart or falsepart based on the value of the - * exprResult - */ - public Object iif(boolean exprResult, Object truepart, Object falsepart) { - return exprResult ? truepart : falsepart; - } - - /** - * - * @param obj1 - * @param obj2 - * @return - */ - public boolean equals(Object obj1, Object obj2) { - if (obj1 == null) { - if (obj2 == null) { - return true; - } - return false; - } - return obj1.equals(obj2); - } - - public boolean isNull(Object obj) { - return null == obj; - } - - public boolean isNotNull(Object obj) { - return null != obj; - } - - public boolean isBlank(String obj) { - return StringUtils.isBlank(obj); - } - - public boolean isNotBlank(String obj) { - return StringUtils.isNotBlank(obj); - } - - @SuppressWarnings("rawtypes") - public boolean isEmpty(Object obj) { - if (obj == null) { - return true; - } - if (obj instanceof Collection) { - return ((Collection) obj).isEmpty(); - } else if (obj instanceof Map) { - return ((Map) obj).isEmpty(); - } else if (obj.getClass().isArray()) { - return Array.getLength(obj) == 0; - } else if (obj instanceof CharSequence) { - return ((CharSequence) obj).length() == 0; - } - return false; - } - - public boolean isNotEmpty(Object obj) { - return !isEmpty(obj); - } - - /** - * Return true if all args are true
- * - * @param objs - * @return - */ - public boolean and(Boolean... objs) { - if (objs != null && objs.length > 0) { - for (int i = 0; i < objs.length; i++) { - if (objs[i] == null || !objs[i]) { - return false; - } - } - return true; - } - return false; - } - - /** - * Return true if any arg is true
- * - * @param objs - * @return - */ - public boolean or(Boolean... objs) { - if (objs != null && objs.length > 0) { - for (int i = 0; i < objs.length; i++) { - if (objs[i] != null && objs[i]) { - return true; - } - } - } - return false; - } - - public boolean not(Boolean obj) { - return !(obj == null ? false : obj); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/DateFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/DateFunc.java deleted file mode 100644 index 86b4266..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/DateFunc.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.function; - -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.TimeZone; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fizzgate.fizz.exception.FizzRuntimeException; - -/** - * Date Functions - * - * @author Francis Dong - * - */ -public class DateFunc implements IFunc { - - private static final Logger LOGGER = LoggerFactory.getLogger(DateFunc.class); - - public static final String DEFAULT_TIMEZONE = "GMT+08:00"; - - private static DateFunc singleton; - - public static DateFunc getInstance() { - if (singleton == null) { - synchronized (DateFunc.class) { - if (singleton == null) { - DateFunc instance = new DateFunc(); - instance.init(); - singleton = instance; - } - } - } - return singleton; - } - - private DateFunc() { - } - - public void init() { - FuncExecutor.register(NAME_SPACE_PREFIX + "date.timestamp", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "date.getTime", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "date.now", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "date.add", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "date.formatTs", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "date.changePattern", this); - } - - /** - * Date pattern
- * yyyy-MM-dd - */ - public final static String DATE_FORMAT = "yyyy-MM-dd"; - - /** - * Time pattren
- * HH:mm:ss - */ - public final static String TIME_FORMAT = "HH:mm:ss"; - - /** - * Short time pattren
- * HH:mm - */ - public final static String SHORT_TIME_FORMAT = "HH:mm"; - - /** - * Date time pattern
- * yyyy-MM-dd HH:mm:ss - */ - public final static String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; - - /** - * Returns current timestamp (Milliseconds) - * - * @return - */ - public long timestamp() { - return System.currentTimeMillis(); - } - - /** - * Returns the number of milliseconds since January 1, 1970, 00:00:00 GMT - * represented by this Date object. - * - * @param date date string - * @param pattern Date time pattern - * @param timeZone [optional] timeZone - * @return - */ - public Long getTime(String date, String pattern, String... timeZone) { - if (StringUtils.isBlank(date)) { - return null; - } - Date d = parse(date, pattern, timeZone); - return d.getTime(); - } - - /** - * Returns current time with the given pattern
- * Frequently-used pattern:
- * yyyy-MM-dd HH:mm:ss
- * yyyy-MM-dd
- * HH:mm:ss
- * HH:mm
- * yyyy-MM-dd HH:mm:ss Z
- * - * @param pattern the pattern describing the date and time format, dafault - * yyyy-MM-dd HH:mm:ss - * @param timeZone [optional] timeZone - * @return - */ - public String now(String pattern, String... timeZone) { - return formatDate(new Date(), pattern, timeZone); - } - - /** - * Adds or subtracts the specified amount of time to the given calendar field, - * based on the calendar's rules. For example, to subtract 5 hours from the - * current time of the calendar, you can achieve it by calling: - *

- * add("2021-08-04 14:23:12", "yyyy-MM-dd HH:mm:ss", 4, -5). - * - * @param date date string - * @param pattern date pattern of the given date string - * @param field the calendar field,
- * 1 for millisecond
- * 2 for second
- * 3 for minute
- * 4 for hour
- * 5 for date
- * 6 for month
- * 7 for year
- * @param amount the amount of date or time to be added to the field - * @param timeZone [optional] timeZone - * @return - */ - public String add(String date, String pattern, int field, int amount, String... timeZone) { - if (StringUtils.isBlank(date)) { - return null; - } - Date d = parse(date, pattern, timeZone); - if (d != null) { - // convert to calendar field - int calField = 0; - switch (field) { - case 1: - calField = Calendar.MILLISECOND; - break; - case 2: - calField = Calendar.SECOND; - break; - case 3: - calField = Calendar.MINUTE; - break; - case 4: - calField = Calendar.HOUR; - break; - case 5: - calField = Calendar.DATE; - break; - case 6: - calField = Calendar.MONTH; - break; - case 7: - calField = Calendar.YEAR; - break; - default: - LOGGER.error("invalid field, date={} pattern={} filed={}", date, pattern, field); - throw new FizzRuntimeException( - "invalid field, date=" + date + "pattern=" + pattern + " filed=" + field); - } - return formatDate(addToFiled(d, calField, amount), pattern, timeZone); - } - return null; - } - - /** - * Format the a timestamp to the given pattern - * - * @param timestamp - * @param pattern - * @param timeZone [optional] timeZone - * @return - */ - public String formatTs(Long timestamp, String pattern, String... timeZone) { - if (timestamp == null) { - return null; - } - return formatDate(new Date(timestamp), pattern, timeZone); - } - - /** - * Format the a time with source pattern to the target pattern - * - * @param dateStr date - * @param sourcePattern source pattern - * @param targetPattern target pattern - * @param timeZone [optional] timeZone - * @return - */ - public String changePattern(String dateStr, String sourcePattern, String targetPattern, String... timeZone) { - if (StringUtils.isBlank(dateStr)) { - return null; - } - return formatDate(parse(dateStr, sourcePattern, timeZone), targetPattern, timeZone); - } - - /** - * Adds or subtracts the specified amount of time to the given calendar field - * - * @param date a Date - * @param field field that the times to be add to, such as: Calendar.SECOND, - * Calendar.YEAR - * @param amount the amount of date or time to be added to the field - * @return - */ - private Date addToFiled(Date date, int field, int amount) { - Calendar cal = Calendar.getInstance(); - cal.setTime(date); - cal.add(field, amount); - return cal.getTime(); - } - - /** - * Parse string to Date - * - * @param dateStr String to be parsed - * @param pattern pattern of dateStr - * @param timeZone [optional] timeZone - * @return - */ - private Date parse(String dateStr, String pattern, String... timeZone) { - if (StringUtils.isBlank(dateStr)) { - return null; - } - SimpleDateFormat sdf = new SimpleDateFormat(pattern == null ? DATE_TIME_FORMAT : pattern); - if (timeZone != null && timeZone.length > 0) { - sdf.setTimeZone(TimeZone.getTimeZone(timeZone[0])); - } else { - sdf.setTimeZone(TimeZone.getTimeZone(DEFAULT_TIMEZONE)); - } - try { - return sdf.parse(dateStr); - } catch (ParseException e) { - LOGGER.error("Parse date error, dateStr={} pattern={}", dateStr, pattern, e); - throw new FizzRuntimeException("Parse date error, dateStr=" + dateStr + " pattern=" + pattern, e); - } - } - - /** - * Format date with the given pattern
- * Frequently-used pattern:
- * yyyy-MM-dd HH:mm:ss
- * yyyy-MM-dd
- * HH:mm:ss
- * HH:mm
- * yyyy-MM-dd HH:mm:ss Z
- * - * @param pattern [optional] the pattern describing the date and time format, - * dafault yyyy-MM-dd HH:mm:ss - * @param timeZone [optional] timeZone - * @return - */ - private String formatDate(Date date, String pattern, String... timeZone) { - if (date == null) { - return null; - } - SimpleDateFormat sdf = new SimpleDateFormat(pattern == null ? DATE_TIME_FORMAT : pattern); - if (timeZone != null && timeZone.length > 0) { - sdf.setTimeZone(TimeZone.getTimeZone(timeZone[0])); - } else { - sdf.setTimeZone(TimeZone.getTimeZone(DEFAULT_TIMEZONE)); - } - return sdf.format(date); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/FuncExecutor.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/FuncExecutor.java deleted file mode 100644 index 4292196..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/FuncExecutor.java +++ /dev/null @@ -1,535 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import java.lang.reflect.Array; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import org.apache.commons.beanutils.ConvertUtils; -import org.apache.commons.lang3.StringUtils; -import org.noear.snack.ONode; -import org.reflections.Reflections; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.input.Input; -import com.fizzgate.fizz.input.PathMapping; - -import lombok.AllArgsConstructor; -import lombok.Data; -import lombok.NoArgsConstructor; - -/** - * Function Register - * - * @author Francis Dong - * - */ -public class FuncExecutor { - - private static final Logger LOGGER = LoggerFactory.getLogger(FuncExecutor.class); - - private static final Map funcMap = new HashMap<>(); - - private static Pattern NUMBER_PATTERN = Pattern - .compile("^[-\\+]?[\\d]+\\s*[,\\)]{1}|^[-\\+]?[\\d]+\\.[\\d]+\\s*[,\\)]{1}"); - - private static Pattern FLOAT_PATTERN = Pattern.compile("^[-\\+]?[\\d]+\\.[\\d]+\\s*[,\\)]{1}"); - - private static FuncExecutor singleton; - - public static FuncExecutor getInstance() { - if (singleton == null) { - synchronized (FuncExecutor.class) { - if (singleton == null) { - singleton = new FuncExecutor(); - init(); - } - } - } - return singleton; - } - - private FuncExecutor() { - } - - public static void init() { - try { - Reflections reflections = new Reflections("com.fizzgate.fizz.function"); - Set> types = reflections.getSubTypesOf(IFunc.class); - for (Class fnType : types) { - Method method = fnType.getMethod("getInstance"); - method.invoke(fnType); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - - /** - * Register a function instance - * - * @param namespace a name to identify the given function instance - * @param func - */ - public static void register(String namespace, IFunc funcInstance) { - if (StringUtils.isBlank(namespace)) { - LOGGER.warn("namespace is required"); - return; - } - if (!namespace.startsWith(IFunc.NAME_SPACE_PREFIX)) { - LOGGER.warn("namespace must start with fn."); - return; - } - if (funcInstance == null) { - LOGGER.warn("function instance is required"); - return; - } - funcMap.put(namespace, funcInstance); - } - - /** - * Execute function - * - * @param funcExpression - * @return - */ - public Object exec(ONode ctxNode, String funcExpression) { - RecursionContext ctx = new RecursionContext(); - ctx.setFuncExpression(funcExpression); - return doExec(ctxNode, ctx); - } - - private Object doExec(ONode ctxNode, RecursionContext ctx) { - String funcExpression = ctx.funcExpression; - if (StringUtils.isBlank(funcExpression)) { - return null; - } - funcExpression = StringUtils.trim(funcExpression); - int pos1 = funcExpression.indexOf("("); - if (pos1 == -1) { - LOGGER.warn("func expression is invalid, expression: {}", funcExpression); - return null; - } - if (!funcExpression.endsWith(")")) { - LOGGER.warn("func expression is invalid, expression: {}", funcExpression); - return null; - } - - String path = funcExpression.substring(0, pos1); - int lastDotPos = path.lastIndexOf("."); - if (pos1 == -1) { - LOGGER.warn("func expression is invalid, expression: {}", funcExpression); - return null; - } - String namespace = path.substring(0, lastDotPos); - String methodName = path.substring(lastDotPos + 1); - - Object funcInstance = funcMap.get(path); - if (funcInstance == null) { - String msg = String.format("function not found: %s, expression: %s", path, funcExpression); - LOGGER.warn(msg); - throw new FizzRuntimeException(msg); - } - - try { - Method method = findMethod(funcInstance.getClass(), methodName); - Class[] paramTypes = method.getParameterTypes(); - ctx.funcExpression = funcExpression; - Object[] args = parseArgs(ctxNode, ctx, funcExpression, paramTypes, method.isVarArgs()); - if (args == null) { - return method.invoke(funcInstance); - } - return method.invoke(funcInstance, args); - } catch (FizzRuntimeException e) { - throw e; - } catch (InvocationTargetException e) { - Throwable targetEx = e.getTargetException(); - if (targetEx instanceof FizzRuntimeException) { - throw (FizzRuntimeException) targetEx; - } - String msg = targetEx.getMessage(); - if (msg == null) { - msg = String.format("execute function error: %s", funcExpression); - } - LOGGER.error(msg, targetEx); - throw new FizzRuntimeException(msg, targetEx); - } catch (Exception e) { - String msg = String.format("execute function error: %s", funcExpression); - LOGGER.error(msg, e); - throw new FizzRuntimeException(msg, e); - } - } - - private Method findMethod(Class funcClass, String methodName) { - Method[] methods = funcClass.getDeclaredMethods(); - for (Method method : methods) { - if (method.getName().equals(methodName)) { - return method; - } - } - String msg = String.format("method not found: %s, class: %s", methodName, funcClass); - LOGGER.warn(msg); - throw new FizzRuntimeException(msg); - } - - /** - * funcExpression sample:
- * fn.date.add({step1.request1.response.body.date}, "yyyy-MM-dd HH:mm:ss", 1, - * 1000)
- * fn.date.add(true, fn.date.add({step1.request1.response.body.date}, - * "yyyy-MM-dd HH:mm:ss", 1, 1000), "yyyy-MM-dd HH:mm:ss\"))}}", 1, 1000)
- * - * @param funcExpression - * @param paramTypes - * @return - */ - private Object[] parseArgs(ONode ctxNode, RecursionContext ctx, String funcExpression, Class[] paramTypes, - boolean isVarArgs) { - int pos1 = funcExpression.indexOf("("); - // int pos2 = funcExpression.lastIndexOf(")"); - String argsStr = funcExpression.substring(pos1 + 1); - argsStr = StringUtils.trim(argsStr); - - Object[] args = new Object[paramTypes.length]; - if (paramTypes.length == 0) { - // no argument method - if (hasCloseParenthesis(argsStr, 0)) { - ctx.funcExpression = argsStr.substring(1); - } else { - ctx.funcExpression = argsStr; - } - return args; - } - // check if there is any argument - if (StringUtils.isBlank(argsStr)) { - if (paramTypes == null || paramTypes.length == 0) { - ctx.funcExpression = argsStr; - return args; - } else if (paramTypes.length == 1 && isVarArgs) { - // check if variable arguments - ctx.funcExpression = argsStr; - return args; - } else { - throw new FizzRuntimeException( - String.format("missing argument, Function Expression: %s", funcExpression)); - } - } else if (hasCloseParenthesis(argsStr, 0)) { - if (paramTypes == null || paramTypes.length == 0) { - ctx.funcExpression = argsStr.substring(1); - return args; - } else if (paramTypes.length == 1 && isVarArgs) { - ctx.funcExpression = argsStr.substring(1); - return args; - } else { - throw new FizzRuntimeException( - String.format("missing argument, Function Expression: %s", funcExpression)); - } - } - - List varArgs = new ArrayList<>(); - for (int i = 0; i < paramTypes.length; i++) { - Class clazz = paramTypes[i]; - if (StringUtils.isBlank(argsStr)) { - if (isVarArgs && i == paramTypes.length - 1 && args[i] == null) { - args[i] = Array.newInstance(clazz.getComponentType(), 0); - } - break; - } - ArgsStrContainer argsStrContainer = new ArgsStrContainer(argsStr, i); - if (argsStr.startsWith("\"")) { // string - int pos = findStringEngPos(argsStr); - if (pos != -1) { - String arg = argsStr.substring(1, pos); - if (isVarArgs && i == paramTypes.length - 1) { - varArgs.add(arg); - args[i] = varArgs.toArray(new String[varArgs.size()]); - } else { - args[i] = arg; - } - argsStrContainer = this.trimArgStr(argsStrContainer, pos + 1, isVarArgs, paramTypes.length, - funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } else { - throw new FizzRuntimeException( - String.format("invalid argument: %s, Function Expression: %s", argsStr, funcExpression)); - } - } else if (argsStr.matches("^null\\s*,.*") || argsStr.matches("^null\\s*\\).*")) { // null - if (isVarArgs && i == paramTypes.length - 1) { - varArgs.add(null); - Object arr = Array.newInstance(clazz.getComponentType(), varArgs.size()); - for (int j = 0; j < varArgs.size(); j++) { - Array.set(arr, j, varArgs.get(j)); - } - args[i] = arr; - } else { - args[i] = null; - } - argsStrContainer = this.trimArgStr(argsStrContainer, 4, isVarArgs, paramTypes.length, funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } else if (argsStr.matches("^true\\s*,.*") || argsStr.matches("^true\\s*\\).*")) { // boolean - if (isVarArgs && i == paramTypes.length - 1) { - varArgs.add(true); - args[i] = varArgs.toArray(new Boolean[varArgs.size()]); - } else { - args[i] = true; - } - argsStrContainer = this.trimArgStr(argsStrContainer, 4, isVarArgs, paramTypes.length, funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } else if (argsStr.matches("^false\\s*,.*") || argsStr.matches("^false\\s*\\).*")) { // boolean - if (isVarArgs && i == paramTypes.length - 1) { - varArgs.add(false); - args[i] = varArgs.toArray(new Boolean[varArgs.size()]); - } else { - args[i] = false; - } - argsStrContainer = this.trimArgStr(argsStrContainer, 5, isVarArgs, paramTypes.length, funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } else if (argsStr.startsWith("{")) { // reference value - int pos = argsStr.indexOf("}", 1); - if (pos != -1) { - String refKey = argsStr.substring(1, pos); - Object arg = PathMapping.getValueByPath(ctxNode, refKey); - if (isVarArgs && i == paramTypes.length - 1) { - arg = ConvertUtils.convert(arg, clazz.getComponentType()); - varArgs.add(arg); - Object arr = Array.newInstance(clazz.getComponentType(), varArgs.size()); - for (int j = 0; j < varArgs.size(); j++) { - Array.set(arr, j, varArgs.get(j)); - } - args[i] = arr; - - } else { - arg = ConvertUtils.convert(arg, clazz); - args[i] = arg; - } - - argsStrContainer = this.trimArgStr(argsStrContainer, pos + 1, isVarArgs, paramTypes.length, - funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } else { - throw new FizzRuntimeException( - String.format("invalid argument: %s, Function Expression: %s", argsStr, funcExpression)); - } - } else { - Matcher m = NUMBER_PATTERN.matcher(argsStr); - boolean isNumber = m.find(); - if (isNumber) { - int pos = m.end(); - String matchedStr = m.group(); - // Number - String strNum = StringUtils.trim(matchedStr.substring(0, pos - 1)); - if (isVarArgs && i == paramTypes.length - 1) { - Object arg = null; - if (clazz.getComponentType().equals(Object.class)) { - if (FLOAT_PATTERN.matcher(argsStr).find()) { - arg = ConvertUtils.convert(strNum, Double.class); - } else { - arg = ConvertUtils.convert(strNum, Long.class); - } - } else { - arg = ConvertUtils.convert(strNum, clazz.getComponentType()); - } - varArgs.add(arg); - Object arr = Array.newInstance(clazz.getComponentType(), varArgs.size()); - for (int j = 0; j < varArgs.size(); j++) { - Array.set(arr, j, varArgs.get(j)); - } - args[i] = arr; - } else { - Object arg = null; - if (clazz.equals(Object.class)) { - if (FLOAT_PATTERN.matcher(argsStr).find()) { - arg = ConvertUtils.convert(strNum, Double.class); - } else { - arg = ConvertUtils.convert(strNum, Long.class); - } - } else { - arg = ConvertUtils.convert(strNum, clazz); - } - args[i] = arg; - } - argsStrContainer = this.trimArgStr(argsStrContainer, pos - 1, isVarArgs, paramTypes.length, - funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } else { - // function - ctx.funcExpression = argsStr; - Object rs = doExec(ctxNode, ctx); - if (isVarArgs && i == paramTypes.length - 1) { - Object arg = ConvertUtils.convert(rs, clazz.getComponentType()); - varArgs.add(arg); - Object arr = Array.newInstance(clazz.getComponentType(), varArgs.size()); - for (int j = 0; j < varArgs.size(); j++) { - Array.set(arr, j, varArgs.get(j)); - } - args[i] = arr; - } else { - Object arg = ConvertUtils.convert(rs, clazz); - args[i] = arg; - } - argsStr = ctx.funcExpression; - argsStrContainer.setArgsStr(argsStr); - argsStrContainer = this.trimArgStr(argsStrContainer, 0, isVarArgs, paramTypes.length, - funcExpression); - argsStr = argsStrContainer.getArgsStr(); - i = argsStrContainer.getIndex(); - } - } - ctx.funcExpression = argsStr; - } - return args; - } - - private ArgsStrContainer trimArgStr(ArgsStrContainer argsStrContainer, int fromIndex, boolean isVarArgs, - int paramTypesLen, String funcExpression) { - int i = argsStrContainer.getIndex(); - String argsStr = argsStrContainer.getArgsStr(); - if (i == paramTypesLen - 1 || (isVarArgs && i == paramTypesLen - 2)) { - boolean hasMore = hasMoreArg(argsStr, fromIndex); - if (isVarArgs && hasMore) { - argsStr = removeComma(argsStr, fromIndex, funcExpression); - if (i == paramTypesLen - 1) { - i--; - } - } else { - if (hasCloseParenthesis(argsStr, fromIndex)) { - argsStr = removeCloseParenthesis(argsStr, fromIndex, funcExpression); - i++; - } else { - throw new FizzRuntimeException(String.format("invalid argument: %s, Function Expression: %s", - argsStr.substring(fromIndex), funcExpression)); - } - } - } else { - argsStr = removeComma(argsStr, fromIndex, funcExpression); - } - argsStrContainer.setArgsStr(argsStr); - argsStrContainer.setIndex(i); - return argsStrContainer; - } - - private boolean hasMoreArg(String argsStr, int fromIndex) { - final int strLen = argsStr.length(); - if (strLen == 0) { - return false; - } - for (int i = fromIndex; i < strLen; i++) { - if (!Character.isWhitespace(argsStr.charAt(i))) { - if (",".equals(String.valueOf(argsStr.charAt(i)))) { - return true; - } else { - return false; - } - } - } - return false; - } - - private boolean hasCloseParenthesis(String argsStr, int fromIndex) { - final int strLen = argsStr.length(); - if (strLen == 0) { - return false; - } - for (int i = fromIndex; i < strLen; i++) { - if (!Character.isWhitespace(argsStr.charAt(i))) { - if (")".equals(String.valueOf(argsStr.charAt(i)))) { - return true; - } else { - return false; - } - } - } - return false; - } - - private String removeComma(String argsStr, int fromIndex, String funcExpression) { - final int strLen = argsStr.length(); - if (strLen == 0) { - return argsStr; - } - for (int i = fromIndex; i < strLen; i++) { - if (!Character.isWhitespace(argsStr.charAt(i))) { - if (",".equals(String.valueOf(argsStr.charAt(i)))) { - return StringUtils.trim(argsStr.substring(i + 1)); - } - } - } - throw new FizzRuntimeException(String.format("missing comma after argument: %s, Function Expression: %s", - argsStr.substring(fromIndex), funcExpression)); - } - - private String removeCloseParenthesis(String argsStr, int fromIndex, String funcExpression) { - final int strLen = argsStr.length(); - if (strLen == 0 || strLen < fromIndex) { - return argsStr; - } - for (int i = fromIndex; i < strLen; i++) { - if (!Character.isWhitespace(argsStr.charAt(i))) { - if (")".equals(String.valueOf(argsStr.charAt(i)))) { - return StringUtils.trim(argsStr.substring(i + 1)); - } - } - } - throw new FizzRuntimeException( - String.format("missing close parenthesis after argument: %s, Function Expression: %s", - argsStr.substring(fromIndex), funcExpression)); - } - - private int findStringEngPos(String ep) { - int pos = ep.indexOf("\"", 1); - while (pos != -1) { - String prevChar = ep.substring(pos - 1, pos); - if (!"\\".equals(prevChar)) { - return pos; - } - pos = ep.indexOf("\"", pos + 1); - } - return -1; - } - -} - -@Data -@AllArgsConstructor -class ArgsStrContainer { - private String argsStr; - private int index; -} - -@Data -@AllArgsConstructor -@NoArgsConstructor -class RecursionContext { - public String funcExpression; - public Object result; -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/IFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/IFunc.java deleted file mode 100644 index 3af99d4..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/IFunc.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -/** - * Function interface - * - * @author Francis Dong - * - */ -public interface IFunc { - - public final static String NAME_SPACE_PREFIX = "fn."; - - /** - * Init: Register functions to FuncExecutor in the initial stage
- *
- * Example:
- * FuncExecutor.register(NAME_SPACE_PREFIX + "date.timestamp", getInstance());
- * FuncExecutor.register(NAME_SPACE_PREFIX + "date.now", getInstance());
- * - */ - void init(); - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/ListFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/ListFunc.java deleted file mode 100644 index 7c41a49..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/ListFunc.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.function; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fizzgate.fizz.exception.FizzRuntimeException; - -/** - * List Functions - * - * @author Francis Dong - * - */ -public class ListFunc implements IFunc { - - private static final Logger LOGGER = LoggerFactory.getLogger(ListFunc.class); - - private static ListFunc singleton; - - public static ListFunc getInstance() { - if (singleton == null) { - synchronized (ListFunc.class) { - if (singleton == null) { - ListFunc instance = new ListFunc(); - instance.init(); - singleton = instance; - } - } - } - return singleton; - } - - private ListFunc() { - } - - public void init() { - FuncExecutor.register(NAME_SPACE_PREFIX + "list.expand", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "list.merge", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "list.extract", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "list.join", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "list.rename", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "list.removeFields", this); - } - - /** - * Expand sublist item to the first level - * - * @param data - * @return - */ - public List expand(List> data) { - List result = new ArrayList<>(); - if (data == null || data.size() == 0) { - return result; - } - for (List list : data) { - result.addAll(list); - } - return result; - } - - /** - * Merge multiple list into one list - * - * @param data - * @return - */ - public List merge(List... data) { - List result = new ArrayList<>(); - if (data == null || data.length == 0) { - return result; - } - for (List list : data) { - if (list == null || list.size() == 0) { - continue; - } - result.addAll(list); - } - return result; - } - - /** - * Extract fields from list - * - * @param data - * @param fields - * @return - */ - public List> extract(List> data, String... fields) { - List> result = new ArrayList<>(); - if (data == null || data.size() == 0) { - return result; - } - if (fields == null || fields.length == 0) { - return data; - } - for (Map m : data) { - Map r = new HashMap<>(); - for (String field : fields) { - r.put(field, m.get(field)); - } - result.add(r); - } - return result; - } - - /** - * Merge fields of source list to destination list join by the join field - * - * @param dest destination list - * @param src source list - * @param joinField join field, pattern: joinFieldOfDest:joinFieldOfSrc, - * :joinFieldOfSrc could be omitted if both join field names - * are the same - * @param fields fields which will be merge to destination list, all fields - * will be merged if it is null - * @return - */ - public List> join(List> dest, List> src, - String joinField, String... fields) { - if (dest == null || dest.size() == 0 || src == null || src.size() == 0) { - return dest; - } - String[] joinFields = joinField.split(":"); - if (joinFields.length == 1) { - joinFields = new String[] {joinField, joinField}; - } - Map> index = new HashMap<>(); - for (Map item : src) { - if (item.get(joinFields[1]) != null) { - index.putIfAbsent(item.get(joinFields[1]).toString(), item); - } - } - - for (Map m : dest) { - Object srcJoinFieldVal = m.get(joinFields[0]); - if (srcJoinFieldVal == null || !index.containsKey(srcJoinFieldVal.toString())) { - continue; - } - Map record = index.get(srcJoinFieldVal.toString()); - - if (fields == null || fields.length == 0) { - m.putAll(record); - } else { - for (String field : fields) { - m.put(field, record.get(field)); - } - } - - } - return dest; - } - - /** - * Rename fields of list - * - * @param data list - * @param fieldPairs old and new key pair of map of list, pattern: - * oldFieldName:newFieldName - * @return - */ - public List> rename(List> data, String... fieldPairs) { - if (data == null || data.size() == 0) { - return data; - } - if (fieldPairs == null || fieldPairs.length == 0) { - return data; - } - - for (Map m : data) { - for (String fieldPair : fieldPairs) { - String[] parts = fieldPair.split(":"); - if (parts == null || parts.length != 2) { - LOGGER.warn("invalid fieldPair: {} , field pair pattern is: oldFieldName:newFieldName", fieldPair); - throw new FizzRuntimeException( - "invalid fieldPair: " + fieldPair + " , field pair pattern is: oldFieldName:newFieldName"); - } - if (m.containsKey(parts[0])) { - m.put(parts[1], m.get(parts[0])); - m.remove(parts[0]); - } - } - } - return data; - } - - /** - * Remove fields from list - * - * @param data - * @param fields fields to be removed - * @return - */ - public List> removeFields(List> data, String... fields) { - if (data == null || data.size() == 0) { - return data; - } - if (fields == null || fields.length == 0) { - return data; - } - for (Map m : data) { - for (String field : fields) { - m.remove(field); - } - } - return data; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/MathFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/MathFunc.java deleted file mode 100644 index 39c5752..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/MathFunc.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import java.math.BigDecimal; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Math Functions - * - * @author Francis Dong - * - */ -@SuppressWarnings("unused") -public class MathFunc implements IFunc { - - private static final Logger LOGGER = LoggerFactory.getLogger(MathFunc.class); - - private static MathFunc singleton; - - public static MathFunc getInstance() { - if (singleton == null) { - synchronized (MathFunc.class) { - if (singleton == null) { - MathFunc instance = new MathFunc(); - instance.init(); - singleton = instance; - } - } - } - return singleton; - } - - private MathFunc() { - } - - public void init() { - FuncExecutor.register(NAME_SPACE_PREFIX + "math.absExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.negateExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.addExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.subtractExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.multiplyExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.maxExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.minExact", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.mod", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.pow", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.sqrt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.random", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.absDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.negateDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.addDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.subtractDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.multiplyDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.divideDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.maxDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.minDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.scaleDecimal", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.compare", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.equals", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.lt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.le", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.gt", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "math.ge", this); - } - - public long absExact(long a) { - return Math.abs(a); - } - - public long negateExact(long a) { - return Math.negateExact(a); - } - - public long addExact(long x, long y) { - return Math.addExact(x, y); - } - - public long subtractExact(long x, long y) { - return Math.subtractExact(x, y); - } - - public long multiplyExact(long x, long y) { - return Math.multiplyExact(x, y); - } - - public long maxExact(long x, long y) { - return Math.max(x, y); - } - - public long minExact(long x, long y) { - return Math.min(x, y); - } - - public long mod(long x, long y) { - return Math.floorMod(x, y); - } - - public double pow(double a, double b) { - return Math.pow(a, b); - } - - public double sqrt(double a) { - return Math.sqrt(a); - } - - /** - * Returns a {@code double} value with a positive sign, greater than or equal to - * {@code 0.0} and less than {@code 1.0}. Returned values are chosen - * pseudorandomly with (approximately) uniform distribution from that range. - * - * @return - */ - public double random() { - return Math.random(); - } - - public double absDecimal(double a) { - return BigDecimal.valueOf(a).abs().doubleValue(); - } - - public double negateDecimal(double a) { - return BigDecimal.valueOf(a).negate().doubleValue(); - } - - public double addDecimal(double x, double y) { - return BigDecimal.valueOf(x).add(BigDecimal.valueOf(y)).doubleValue(); - } - - public double subtractDecimal(double x, double y) { - return BigDecimal.valueOf(x).subtract(BigDecimal.valueOf(y)).doubleValue(); - } - - public double multiplyDecimal(double x, double y) { - return BigDecimal.valueOf(x).multiply(BigDecimal.valueOf(y)).doubleValue(); - } - - public double divideDecimal(double x, double y) { - return BigDecimal.valueOf(x).divide(BigDecimal.valueOf(y)).doubleValue(); - } - - public double maxDecimal(double x, double y) { - return BigDecimal.valueOf(x).max(BigDecimal.valueOf(y)).doubleValue(); - } - - public double minDecimal(double x, double y) { - return BigDecimal.valueOf(x).min(BigDecimal.valueOf(y)).doubleValue(); - } - - public double scaleDecimal(double a, int scale) { - return BigDecimal.valueOf(a).setScale(scale, BigDecimal.ROUND_HALF_UP).doubleValue(); - } - - /** - * Compares number x with the specified number y. - * - * @param x number - * @param y number - * @return -1, 0, or 1 as x is numerically less than, equal to, or greater than - * y. - */ - public int compare(double x, double y) { - return BigDecimal.valueOf(x).compareTo(BigDecimal.valueOf(y)); - } - - public boolean equals(double x, double y) { - return BigDecimal.valueOf(x).equals(BigDecimal.valueOf(y)); - } - - /** - * Checks if x is less than y - * @param x - * @param y - * @return - */ - public boolean lt(double x, double y) { - return BigDecimal.valueOf(x).compareTo(BigDecimal.valueOf(y)) == -1; - } - - /** - * Checks if x is less than or equals y - * @param x - * @param y - * @return - */ - public boolean le(double x, double y) { - return BigDecimal.valueOf(x).compareTo(BigDecimal.valueOf(y)) <= 0; - } - - /** - * Checks if x is greater than y - * @param x - * @param y - * @return - */ - public boolean gt(double x, double y) { - return BigDecimal.valueOf(x).compareTo(BigDecimal.valueOf(y)) == 1; - } - - /** - * Checks if x is greater than or equals y - * @param x - * @param y - * @return - */ - public boolean ge(double x, double y) { - return BigDecimal.valueOf(x).compareTo(BigDecimal.valueOf(y)) >= 0; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/function/StringFunc.java b/fizz-core/src/main/java/com/fizzgate/fizz/function/StringFunc.java deleted file mode 100644 index cbd9293..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/function/StringFunc.java +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import java.util.UUID; - -import org.apache.commons.lang3.StringUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fizzgate.fizz.exception.FizzRuntimeException; - -/** - * String Functions - * - * @author Francis Dong - * - */ -public class StringFunc implements IFunc { - - private static final Logger LOGGER = LoggerFactory.getLogger(StringFunc.class); - - private static StringFunc singleton; - - public static StringFunc getInstance() { - if (singleton == null) { - synchronized (StringFunc.class) { - if (singleton == null) { - StringFunc instance = new StringFunc(); - instance.init(); - singleton = instance; - } - } - } - return singleton; - } - - private StringFunc() { - } - - public void init() { - FuncExecutor.register(NAME_SPACE_PREFIX + "string.equals", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.equalsIgnoreCase", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.compare", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.concat", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.concatws", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.substring", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.indexOf", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.startsWith", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.endsWith", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.toUpperCase", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.toLowerCase", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.uuid", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.toString", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.replace", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.replaceAll", this); - FuncExecutor.register(NAME_SPACE_PREFIX + "string.replaceFirst", this); - } - - /** - *

- * Compares two Strings, returning {@code true} if they represent equal - * sequences of Strings. - *

- * - *

- * {@code null}s are handled without exceptions. Two {@code null} references are - * considered to be equal. The comparison is case sensitive. - *

- * - *
-	 * equals(null, null)   = true
-	 * equals(null, "abc")  = false
-	 * equals("abc", null)  = false
-	 * equals("abc", "abc") = true
-	 * equals("abc", "ABC") = false
-	 * 
- * - * @param str1 the first String, may be {@code null} - * @param str2 the second String, may be {@code null} - * @return {@code true} if the Strings are equal (case-sensitive), or both - * {@code null} - */ - public boolean equals(String str1, String str2) { - return StringUtils.equals(str1, str2); - } - - /** - *

- * Compares two Strings, returning {@code true} if they represent equal - * sequences of Strings, ignoring case. - *

- * - *

- * {@code null}s are handled without exceptions. Two {@code null} references are - * considered equal. The comparison is case insensitive. - *

- * - *
-	 * equalsIgnoreCase(null, null)   = true
-	 * equalsIgnoreCase(null, "abc")  = false
-	 * equalsIgnoreCase("abc", null)  = false
-	 * equalsIgnoreCase("abc", "abc") = true
-	 * equalsIgnoreCase("abc", "ABC") = true
-	 * 
- * - * @param str1 the first String, may be {@code null} - * @param str2 the second String, may be {@code null} - * @return {@code true} if the Strings are equal (case-insensitive), or both - * {@code null} - */ - public boolean equalsIgnoreCase(String str1, String str2) { - return StringUtils.equalsIgnoreCase(str1, str2); - } - - /** - * Compare two Strings lexicographically - * - * @param str1 - * @param str2 - * @return -1, 0, 1, if {@code str1} is respectively less, equal or greater than - * {@code str2} - */ - public int compare(String str1, String str2) { - int n = StringUtils.compare(str1, str2); - return n == 0 ? 0 : (n > 0 ? 1 : -1); - } - - /** - * Concat strings - * - * @param strs - * @return - */ - public String concat(String... strs) { - return StringUtils.join(strs); - } - - /** - * Concat with separator - * - * @param strs - * @return - */ - public String concatws(String separator, String... strs) { - return StringUtils.join(strs, separator); - } - - /** - * Returns a string that is a substring of this string. The substring begins at - * the specified {@code beginIndex} and extends to the character at index - * {@code endIndex - 1}. Thus the length of the substring is - * {@code endIndex-beginIndex}. - * - * @param str - * @param beginIndex - * @param endIndex - * @return - */ - public String substring(String str, int beginIndex, int... endIndex) { - if (StringUtils.isBlank(str)) { - return str; - } - if (endIndex != null && endIndex.length > 0) { - if (endIndex.length > 1) { - LOGGER.error("invalid argument: endIndex"); - throw new FizzRuntimeException("invalid argument: endIndex"); - } - return str.substring(beginIndex, endIndex[0]); - } - return str.substring(beginIndex); - } - - /** - * Returns the index within this string of the first occurrence of the specified - * substring. - * - * @param str - * @param substr - * @return the index of the first occurrence of the specified substring, or - * {@code -1} if there is no such occurrence. - */ - public int indexOf(String str, String substr) { - if (StringUtils.isBlank(str)) { - return -1; - } - return str.indexOf(substr); - } - - /** - * Tests if this string starts with the specified prefix. - * - * @param prefix the prefix. - * @return {@code true} if the character sequence represented by the argument is - * a prefix of the character sequence represented by this string; - * {@code false} otherwise. Note also that {@code true} will be returned - * if the argument is an empty string or is equal to this {@code String} - * object as determined by the {@link #equals(Object)} method. - */ - public boolean startsWith(String str, String prefix) { - if (StringUtils.isBlank(str)) { - return false; - } - return str.startsWith(prefix); - } - - /** - * Tests if this string starts with the specified prefix. - * - * @param prefix the prefix. - * @return {@code true} if the character sequence represented by the argument is - * a prefix of the character sequence represented by this string; - * {@code false} otherwise. Note also that {@code true} will be returned - * if the argument is an empty string or is equal to this {@code String} - * object as determined by the {@link #equals(Object)} method. - */ - public boolean endsWith(String str, String suffix) { - if (StringUtils.isBlank(str)) { - return false; - } - return str.endsWith(suffix); - } - - public String toUpperCase(String str) { - if (StringUtils.isBlank(str)) { - return str; - } - return str.toUpperCase(); - } - - public String toLowerCase(String str) { - if (StringUtils.isBlank(str)) { - return str; - } - return str.toLowerCase(); - } - - /** - * - * @return UUID - */ - public String uuid() { - return UUID.randomUUID().toString().replaceAll("-", ""); - } - - public String toString(Object obj) { - return obj == null ? null : obj.toString(); - } - - /** - * Replaces each substring of this string that matches the literal target - * sequence with the specified literal replacement sequence. The replacement - * proceeds from the beginning of the string to the end, for example, replacing - * "aa" with "b" in the string "aaa" will result in "ba" rather than "ab". - * - * @param str String - * @param target The sequence of char values to be replaced - * @param replacement The replacement sequence of char values - * @return - */ - public String replace(String str, String target, String replacement) { - return str.replace(target, replacement); - } - - /** - * Replaces each substring of this string that matches the given regular - * expression with the given replacement. - * - * @param str String - * @param regex the regular expression to which this string is to be - * matched - * @param replacement the string to be substituted for each match - * @return - */ - public String replaceAll(String str, String regex, String replacement) { - return str.replaceAll(regex, replacement); - } - - /** - * Replaces the first substring of this string that matches the given regular - * expression with the given replacement. - * - * @param str String - * @param regex the regular expression to which this string is to be - * matched - * @param replacement the string to be substituted for the first match - * @return - */ - public String replaceFirst(String str, String regex, String replacement) { - return str.replaceFirst(regex, replacement); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/ClientInputConfig.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/ClientInputConfig.java deleted file mode 100644 index 8bdffda..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/ClientInputConfig.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import java.util.HashMap; -import java.util.Map; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class ClientInputConfig extends InputConfig { - - private boolean debug; - private String path; - private String method; - private Map headers = new HashMap(); - private Map langDef; - private Map bodyDef; - private Map headersDef; - private Map paramsDef; - private Map scriptValidate; - private Map validateResponse; - private String contentType; - private String xmlArrPaths; - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public ClientInputConfig(Map configBody) { - super(configBody); - if(configBody.get("debug") != null) { - this.debug = (boolean) configBody.get("debug"); - } - this.path = (String) configBody.get("path"); - if (configBody.get("headers") != null) { - setHeaders((Map) configBody.get("headers")); - } - if (configBody.get("method") != null) { - setMethod((String) configBody.get("method")); - } else { - setMethod("GET"); - } - - if (configBody.get("langDef") != null) { - langDef = (Map) configBody.get("langDef"); - } - if (configBody.get("bodyDef") != null) { - bodyDef = (Map) configBody.get("bodyDef"); - } - if (configBody.get("paramsDef") != null) { - paramsDef = (Map) configBody.get("paramsDef"); - } - if (configBody.get("headersDef") != null) { - headersDef = (Map) configBody.get("headersDef"); - } - if (configBody.get("scriptValidate") != null) { - scriptValidate = (Map) configBody.get("scriptValidate"); - } - if (configBody.get("validateResponse") != null) { - validateResponse = (Map) configBody.get("validateResponse"); - } - if (configBody.get("contentType") != null) { - contentType = (String) configBody.get("contentType"); - } - if (configBody.get("xmlArrPaths") != null) { - xmlArrPaths = (String) configBody.get("xmlArrPaths"); - } - } - - public ClientInputConfig() { - super(null); - } - - - public boolean isDebug() { - return debug; - } - - public void setDebug(boolean debug) { - this.debug = debug; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public Map getLangDef() { - return langDef; - } - - public void setLangDef(Map langDef) { - this.langDef = langDef; - } - - public Map getHeaders() { - return headers; - } - - public void setHeaders(Map headers) { - this.headers = headers; - } - - public String getMethod() { - return method; - } - - public void setMethod(String method) { - this.method = method; - } - - public Map getBodyDef() { - return bodyDef; - } - - public void setBodyDef(Map bodyDef) { - this.bodyDef = bodyDef; - } - - public Map getHeadersDef() { - return headersDef; - } - - public void setHeadersDef(Map headersDef) { - this.headersDef = headersDef; - } - - public Map getParamsDef() { - return paramsDef; - } - - public void setParamsDef(Map paramsDef) { - this.paramsDef = paramsDef; - } - - public Map getScriptValidate() { - return scriptValidate; - } - - public void setScriptValidate(Map scriptValidate) { - this.scriptValidate = scriptValidate; - } - - public Map getValidateResponse() { - return validateResponse; - } - - public void setValidateResponse(Map validateResponse) { - this.validateResponse = validateResponse; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - - public String getXmlArrPaths() { - return xmlArrPaths; - } - - public void setXmlArrPaths(String xmlArrPaths) { - this.xmlArrPaths = xmlArrPaths; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/IInput.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/IInput.java deleted file mode 100644 index 434f7a3..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/IInput.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import org.springframework.context.ConfigurableApplicationContext; - -import com.fizzgate.fizz.Step; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.StepResponse; - -import reactor.core.publisher.Mono; - -import java.lang.ref.SoftReference; -import java.lang.reflect.Field; -import java.util.Map; - -public interface IInput { - public static final InputType TYPE = null; - public static Class inputConfigClass() { - return null; - } - public String getName() ; - public boolean needRun(StepContext stepContext); - public void beforeRun(InputContext context); - public Mono run(); - - public StepResponse getStepResponse() ; - public void setStepResponse(StepResponse stepResponse); - public SoftReference getWeakStep(); - public void setWeakStep(SoftReference weakStep); - - public ConfigurableApplicationContext getCurrentApplicationContext(); - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/Input.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/Input.java deleted file mode 100644 index 70cc810..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/Input.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.input; - -import java.lang.ref.SoftReference; -import java.lang.reflect.Field; -import java.util.Map; - - -import org.reflections.Reflections; -import org.springframework.context.ConfigurableApplicationContext; - -import com.fizzgate.fizz.Step; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.StepResponse; - -import reactor.core.publisher.Mono; - -/** - * - * @author linwaiwai - * - */ -public class Input { - protected String name; - protected InputConfig config; - protected InputContext inputContext; - protected StepResponse lastStepResponse = null; - protected StepResponse stepResponse; - private SoftReference weakStep; - public void setConfig(InputConfig inputConfig) { - config = inputConfig; - } - public InputConfig getConfig() { - return config; - } - - public void beforeRun(InputContext context) { - this.inputContext = context; - } - - public String getName() { - if (name == null) { - return name = "input" + (int)(Math.random()*100); - } - return name; - } - - /** - * 检查该Input是否需要运行,默认都运行 - * @stepContext Step上下文 - * @return TRUE:运行 - */ - public boolean needRun(StepContext stepContext) { - return Boolean.TRUE; - } - - public Mono run() { - return null; - } - public void setName(String configName) { - this.name = configName; - - } - - public StepResponse getStepResponse() { - return stepResponse; - } - public void setStepResponse(StepResponse stepResponse) { - this.stepResponse = stepResponse; - } - - public SoftReference getWeakStep() { - return weakStep; - } - - public void setWeakStep(SoftReference weakStep) { - this.weakStep = weakStep; - } - - public ConfigurableApplicationContext getCurrentApplicationContext(){ - return this.getWeakStep() != null ? this.getWeakStep().get().getCurrentApplicationContext() : null; - } - - public static Class inputConfigClass (){ - return InputConfig.class; - } - - public static void initialize(Classclazz) throws IllegalAccessException { - Field field = null; - try { - field = clazz.getDeclaredField("TYPE"); - InputFactory.registerInput((InputType) field.get(null), clazz); - } catch (NoSuchFieldException e) { - // doing nothing is right - } - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputConfig.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/InputConfig.java deleted file mode 100644 index dc45fed..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputConfig.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.fizzgate.fizz.component.IComponent; - -/** - * - * @author linwaiwai - * - */ -public class InputConfig { - - private InputType type; - protected Map dataMapping; - protected Map configMap; - private Map condition; - private List components; - - public Map getCondition() { - return condition; - } - - public void setCondition(Map condition) { - this.condition = condition; - } - - public InputConfig(Map aConfigMap) { - configMap = aConfigMap; - } - - public InputType getType() { - return type; - } - - public void setType(InputType typeEnum) { - this.type = typeEnum; - } - - public Map getDataMapping() { - return dataMapping; - } - - public void setDataMapping(Map dataMapping) { - this.dataMapping = dataMapping; - } - - private Map fallback = new HashMap(); - - public Map getFallback() { - return fallback; - } - - public void setFallback(Map fallback) { - this.fallback = fallback; - } - - public List getComponents() { - return components; - } - - public void setComponents(List components) { - this.components = components; - } - - public void parse(){ - - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputContext.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/InputContext.java deleted file mode 100644 index 95759ac..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputContext.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -package com.fizzgate.fizz.input; - -import java.util.HashMap; -import java.util.Map; - -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.StepResponse; - -/** - * - * @author linwaiwai - * - */ -public class InputContext { - private StepContext stepContext; - private StepResponse lastStepResponse = null; - public InputContext(StepContext stepContext2, StepResponse lastStepResponse2) { - this.stepContext = stepContext2; - this.lastStepResponse = lastStepResponse2; - } - public StepContext getStepContext() { - return stepContext; - } - public void setStepContext(StepContext stepContext) { - this.stepContext = stepContext; - } - public StepResponse getLastStepResponse() { - return lastStepResponse; - } - public void setLastStepResponse(StepResponse lastStepResponse) { - this.lastStepResponse = lastStepResponse; - } -// public Map getResponses() { -// //TODO: -// if (stepContext != null) { -// Map responses = new HashMap(); -// for( String key :stepContext.keySet()) { -// StepResponse stepResponse = (StepResponse)stepContext.get(key); -// responses.put(key, stepResponse.getResponse()); -// } -// return responses; -// } else { -// return null; -// } -// -// -// -// } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputFactory.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/InputFactory.java deleted file mode 100644 index 8ce98ad..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputFactory.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import org.reflections.Reflections; - -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fizzgate.fizz.component.ComponentExecutor; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.input.extension.request.RequestInput; - -/** - * - * @author linwaiwai - * - */ -public class InputFactory { - private static final Logger LOGGER = LoggerFactory.getLogger(InputFactory.class); - public static Map inputClasses = new HashMap(); - public static void registerInput(InputType type, Class inputClass){ - inputClasses.put(type, inputClass); - } - public static void unregisterInput(InputType type){ - inputClasses.remove(type); - } - public static InputConfig createInputConfig(Map config) { - String type = (String) config.get("type"); - InputType typeEnum = InputType.valueOf(type.toUpperCase()); - InputConfig inputConfig = null; - if (inputClasses.containsKey(typeEnum)){ - Class InputClass = inputClasses.get(typeEnum); - - try { - Method inputConfigClassMethod = InputClass.getMethod("inputConfigClass"); - Class InputConfigClass = (Class) inputConfigClassMethod.invoke(null); - Constructor constructor = null; - constructor = InputConfigClass.getDeclaredConstructor(Map.class); - constructor.setAccessible(true); - inputConfig = (InputConfig) constructor.newInstance(config); - } catch (Exception e) { - LOGGER.error("failed to create input config, error: {}", e.getMessage(), e); - throw new FizzRuntimeException("failed to create input config, message: " + e.getMessage(), e); - } - inputConfig.setType(typeEnum); - inputConfig.setDataMapping((Map) config.get("dataMapping")); - inputConfig.setComponents(ComponentExecutor.buildComponents((List>) config.get("components"))); - inputConfig.parse(); - return inputConfig; - } else { - throw new FizzRuntimeException("can't find input config type:" + type); - } - } - - public static Input createInput(String type) { - InputType typeEnum = InputType.valueOf(type.toUpperCase()); - Input input = null; - if (inputClasses.containsKey(typeEnum)) { - Class InputClass = inputClasses.get(typeEnum); - Constructor constructor = null; - try { - constructor = InputClass.getDeclaredConstructor(); - constructor.setAccessible(true); - input = (Input) constructor.newInstance(); - return input; - } catch (Exception e) { - LOGGER.error("failed to create input config, error: {}", e.getMessage(), e); - throw new FizzRuntimeException("failed to create input config, message: " + e.getMessage(), e); - } - } else { - throw new FizzRuntimeException("can't find input type:" + type); - } - } - - public static void loadInputClasses() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - Reflections reflections = new Reflections("com.fizzgate.fizz.input"); - Set> subTypes = reflections.getSubTypesOf(Input.class); - for (ClassinputType : subTypes){ - Method initializeMethod = inputType.getMethod("initialize", Class.class); - initializeMethod.invoke(null, inputType); - } - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputType.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/InputType.java deleted file mode 100644 index e39e0fe..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/InputType.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import java.util.HashMap; -import java.util.Map; - -/** - * - * @author linwaiwai - * - */ - -public class InputType { - - private final String type; - static private Map inputs = new HashMap(); - public InputType(String aType) { - this.type = aType; - inputs.put(aType, this); - } - - public static InputType valueOf(String string) { - return inputs.get(string); - } - public String toString(){ - return type; - } - -} \ No newline at end of file diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/PathMapping.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/PathMapping.java deleted file mode 100644 index f88f4a4..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/PathMapping.java +++ /dev/null @@ -1,596 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; - -import org.apache.commons.lang3.StringUtils; -import org.noear.snack.ONode; - -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.function.FuncExecutor; -import com.fizzgate.fizz.function.IFunc; -import com.fizzgate.global_resource.GlobalResourceService; -import com.fizzgate.util.MapUtil; - -/** - * - * @author Francis Dong - * - */ -public class PathMapping { - - private static final String GLOBAL_RESOURCE_PREFIX = "g."; - - private static List typeList = Arrays.asList("Integer", "int", "Boolean", "boolean", "Float", "float", - "Double", "double", "String", "string", "Long", "long", "Number", "number"); - - public static ONode toONode(Object obj) { - ONode o = null; - synchronized (obj) { - o = ONode.loadObj(obj); - } - return o; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static void setByPath(ONode target, String path, Object obj, boolean supportMultiLevels) { - if (CommonConstants.WILDCARD_STAR.equals(path)) { - if (obj instanceof ONode) { - ONode node = (ONode) obj; - if(node.isObject()) { - target.setAll(node); - } - } else if (obj instanceof Map) { - target.setAll((Map) obj); - } - } else { - String[] keys = path.split("\\."); - if (!supportMultiLevels) { - keys = new String[] { path }; - } - ONode cur = target; - for (int i = 0; i < keys.length - 1; i++) { - cur = cur.getOrNew(keys[i]); - } - - if ((obj instanceof ONode && ((ONode) obj).isArray()) || obj instanceof Collection - || (obj instanceof ONode && ((ONode) obj).isObject()) || obj instanceof Map) { - ONode subNode = cur.getOrNew(keys[keys.length - 1]); - if ((obj instanceof ONode && ((ONode) obj).isArray()) || obj instanceof Collection) { - if (subNode.isArray()) { - if (obj instanceof ONode) { - subNode.addAll((ONode) obj); - } else if (obj instanceof Collection) { - subNode.addAll((Collection) obj); - } - } else { - subNode.fill(obj); - } - } else { - if (subNode.isObject()) { - if (obj instanceof ONode) { - ONode node = (ONode) obj; - if (node.isObject()) { - subNode.setAll(node); - } - } else if (obj instanceof Map) { - subNode.setAll((Map) obj); - } - } else { - subNode.fill(obj); - } - } - } else { - cur.set(keys[keys.length - 1], obj); - } - } - } - - public static Map transformToMap(ONode ctxNode, Map rules, boolean supportMultiLevels) { - ONode target = transform(ctxNode, rules, supportMultiLevels); - return target.toObject(Map.class); - } - - @SuppressWarnings("unchecked") - public static ONode transform(ONode ctxNode, Map rules, boolean supportMultiLevels) { - ONode target = ONode.load(new HashMap()); - if (rules.isEmpty()) { - return target; - } - - Map rs = new HashMap<>(); - Map types = new HashMap<>(); - for (Entry entry : rules.entrySet()) { - if (entry.getValue() instanceof String) { - String val = (String) entry.getValue(); - Optional optType = typeList.stream().filter(s -> val.startsWith(s + " ")).findFirst(); - if (optType.isPresent()) { - rs.put(entry.getKey(), val.substring(optType.get().length() + 1)); - types.put(entry.getKey(), optType.get()); - } else { - rs.put(entry.getKey(), val); - } - } else if (entry.getValue() instanceof List) { - List values = (List) entry.getValue(); - List vList = new ArrayList<>(); - List tList = new ArrayList<>(); - for (Object v : values) { - if (v instanceof String) { - String val = (String) v; - Optional optType = typeList.stream().filter(s -> val.startsWith(s + " ")).findFirst(); - if (optType.isPresent()) { - vList.add(val.substring(optType.get().length() + 1)); - tList.add(optType.get()); - } else { - vList.add(val); - tList.add(null); - } - } - } - rs.put(entry.getKey(), vList); - types.put(entry.getKey(), tList); - } - } - - if (rs.isEmpty()) { - return target; - } - - // wildcard star entry - Object starValObj = null; - String starEntryKey = null; - - for (Entry entry : rs.entrySet()) { - if (entry.getValue() instanceof String) { - String path = (String) entry.getValue(); - String type = (String) types.get(entry.getKey()); - Object obj = getRefValue(ctxNode, type, path); - if (CommonConstants.WILDCARD_STAR.equals(entry.getKey())) { - starValObj = obj; - starEntryKey = entry.getKey(); - } else { - setByPath(target, entry.getKey(), obj, supportMultiLevels); - } - } else if (entry.getValue() instanceof List) { - List refs = (List) entry.getValue(); - List tList = (List) types.get(entry.getKey()); - List refValList = new ArrayList<>(); - for (int i = 0; i < refs.size(); i++) { - String path = refs.get(i); - String type = tList.get(i); - Object obj = getRefValue(ctxNode, type, path); - // Only header form-data and query Parameter support multiple values, merge result into - // one a list - if (obj instanceof List) { - refValList.addAll((List) obj); - } else { - refValList.add(obj); - } - } - setByPath(target, entry.getKey(), refValList, supportMultiLevels); - } - } - - if(starEntryKey != null) { - setByPath(target, starEntryKey, starValObj, supportMultiLevels); - } - return target; - } - - private static Object getRefValue(ONode ctxNode, String type, String path) { - if (StringUtils.isBlank(path)) { - return null; - } - Object obj = null; - // check if it is a function - if (path.startsWith(IFunc.NAME_SPACE_PREFIX)) { - obj = FuncExecutor.getInstance().exec(ctxNode, path); - if (obj != null && type != null) { - obj = cast(obj, type, path); - } - } else { - try { - String p = path; - String defaultValue = null; - if (path.indexOf("|") != -1) { - p = path.substring(0, path.indexOf("|")); - defaultValue = path.substring(path.indexOf("|") + 1); - } - ONode val = null; - if (p.startsWith(GLOBAL_RESOURCE_PREFIX)) { - val = select(GlobalResourceService.resNode, p.substring(GLOBAL_RESOURCE_PREFIX.length())); - } else { - val = select(ctxNode, handlePath(p)); - } - if (val != null && !val.isNull()) { - obj = val; - } else { - obj = defaultValue; - } - if (obj != null && type != null) { - obj = cast(obj, type, path); - } - } catch (Exception e) { - // e.printStackTrace(); - throw new FizzRuntimeException(String.format("path mapping errer: %s , path mapping data: %s %s", e.getMessage(), type, path), e); - } - } - return obj; - } - - private static Object cast(Object obj, String type, String path) { - try { - switch (type) { - case "Integer": - case "int": { - if (obj instanceof ONode) { - obj = ((ONode) obj).val().getInt(); - } else { - obj = Integer.valueOf(obj.toString()); - } - break; - } - case "Boolean": - case "boolean": { - if (obj instanceof ONode) { - obj = ((ONode) obj).val().getBoolean(); - } else { - obj = Boolean.valueOf(obj.toString()); - } - break; - } - case "Float": - case "float": { - if (obj instanceof ONode) { - obj = ((ONode) obj).val().getFloat(); - } else { - obj = Float.valueOf(obj.toString()); - } - break; - } - case "Double": - case "double": { - if (obj instanceof ONode) { - obj = ((ONode) obj).val().getDouble(); - } else { - obj = Double.valueOf(obj.toString()); - } - break; - } - case "String": - case "string": { - if (obj instanceof ONode) { - obj = ((ONode) obj).val().getString(); - } else { - obj = String.valueOf(obj.toString()); - } - break; - } - case "Long": - case "long": { - if (obj instanceof ONode) { - obj = ((ONode) obj).val().getLong(); - } else { - obj = Long.valueOf(obj.toString()); - } - break; - } - } - return obj; - } catch (Exception e) { - // e.printStackTrace(); - throw new FizzRuntimeException(String.format("failed to cast %s to %s, JSON path expression: %s, error: %s", obj, type, path, e.getMessage()), e); - } - } - - public static ONode select(ONode ctxNode, String path) { - ONode val = ctxNode.select("$." + path); - if (val != null && !val.isNull()) { - return val; - } - String[] arr = path.split("\\."); - if (arr.length == 6 && "headers".equals(arr[4]) && arr[5].endsWith("[0]")) { - ONode v = ctxNode.select("$." + path.substring(0, path.length() - 3)); - if (!v.isArray()) { - return v; - } - } - if (arr.length == 4 && "headers".equals(arr[2]) && arr[3].endsWith("[0]")) { - ONode v = ctxNode.select("$." + path.substring(0, path.length() - 3)); - if (!v.isArray()) { - return v; - } - } - return val; - } - - /** - * Returns value of path, return default value if no value matched by path - * - * @param ctxNode - * @param path e.g: step1.request1.headers.abc or - * step1.request1.headers.abc|123 (default value separate by "|") - * @return - */ - public static Object getValueByPath(ONode ctxNode, String path) { - return getValueByPath(ctxNode, null, path); - } - - /** - * Returns value of path, return default value if no value matched by path - * - * @param ctxNode - * @param type - * @param path e.g: step1.request1.headers.abc or - * step1.request1.headers.abc|123 (default value separate by "|") - * @return - */ - public static Object getValueByPath(ONode ctxNode, String type, String path) { -// if (StringUtils.isBlank(path)) { -// return null; -// } -// String p = path; -// String defaultValue = null; -// if (path.indexOf("|") != -1) { -// p = path.substring(0, path.indexOf("|")); -// defaultValue = path.substring(path.indexOf("|") + 1); -// } -// ONode val = null; -// if (p.startsWith(GLOBAL_RESOURCE_PREFIX)) { -// val = select(GlobalResourceService.resNode, p.substring(GLOBAL_RESOURCE_PREFIX.length())); -// } else { -// val = select(ctxNode, handlePath(p)); -// } -// if (val != null && !val.isNull()) { -// return val.toData(); -// } -// return defaultValue; - Object val = getRefValue(ctxNode, type, path); - if (val != null && val instanceof ONode) { - ONode oval = (ONode)val; - if (!oval.isNull()) { - return oval.toData(); - } else { - return val; - } - } - return val; - } - - public static Map getScriptRules(Map rules) { - if (rules.isEmpty()) { - return new HashMap<>(); - } - Map rs = new HashMap<>(); - for (Entry entry : rules.entrySet()) { - if (entry.getValue() instanceof List) { - List values = (List) entry.getValue(); - for (Object v : values) { - if (!(v instanceof String)) { - rs.put(entry.getKey(), v); - } - } - } else if (!(entry.getValue() instanceof String) && entry.getValue() instanceof Map) { - rs.put(entry.getKey(), entry.getValue()); - } - } - return rs; - } - - /** - * 把Path转为context里的实际路径
- * 步骤兼容以下几种写法,把后几种转换为第一种标准路径
- * - * 例子1:
- * step1.requests.request1.request.headers
- * step1.request1.request.headers
- * step1.request1.requestHeaders
- * step1.requests.request1.requestHeaders
- * - * 例子2:
- * step1.requests.request1.response.body
- * step1.request1.response.body
- * step1.request1.responseBody
- * step1.requests.request1.responseBody
- * - * input兼容以下写法,把第二种转换为第一种标准路径
- * - * 例子1:
- * input.request.headers
- * input.requestHeaders
- * - * 例子2:
- * input.response.body
- * input.responseBody
- * - * @param path - * @return - */ - public static String handlePath(String path) { - if(path.startsWith("step")) { - String[] arr = path.split("\\."); - - List list = Arrays.stream(arr).collect(Collectors.toList()); - // 补齐 requests - // fix-如果是从step*.result下获取数据不应该插入requests - if(list.size() >= 2 && !"requests".equals(list.get(1)) && !"result".equals(list.get(1))) { - list.add(1,"requests"); - } - - // 拆分一级为两级,如:requestBody -> request.body - if(list.size() >= 4) { - String s = list.get(3); - switch (s) { - case "requestHeaders": - list.set(3, "headers"); - list.add(3, "request"); - break; - case "requestParams": - list.set(3, "params"); - list.add(3, "request"); - break; - case "requestBody": - list.set(3, "body"); - list.add(3, "request"); - break; - case "responseHeaders": - list.set(3, "headers"); - list.add(3, "response"); - break; - case "responseBody": - list.set(3, "body"); - list.add(3, "response"); - break; - } - } - - // upper case header name - if (list.size() > 5 && "headers".equals(list.get(4))) { - String headerName = list.get(5).toUpperCase(); - list.set(5, headerName); - } - return String.join(".", list); - }else if(path.startsWith("input")) { - String[] arr = path.split("\\."); - - List list = Arrays.stream(arr).collect(Collectors.toList()); - - // 拆分一级为两级,如:requestBody -> request.body - if(list.size() >= 2) { - String s = list.get(1); - switch (s) { - case "requestHeaders": - list.set(1, "headers"); - list.add(1, "request"); - break; - case "requestParams": - list.set(1, "params"); - list.add(1, "request"); - break; - case "requestBody": - list.set(1, "body"); - list.add(1, "request"); - break; - case "responseHeaders": - list.set(1, "headers"); - list.add(1, "response"); - break; - case "responseBody": - list.set(1, "body"); - list.add(1, "response"); - break; - } - } - // upper case header name - if (list.size() > 3 && "headers".equals(list.get(2))) { - String headerName = list.get(3).toUpperCase(); - list.set(3, headerName); - } - return String.join(".", list); - - }else { - return path; - } - } - - /** - * 数据转换 - * - * @param ctxNode - * @param stepContext - * @param fixed optional - * @param mappingRules optional - * @return - */ - public static Map transform(ONode ctxNode, StepContext stepContext, - Map fixed, Map mappingRules) { - return transform(ctxNode, stepContext, fixed, mappingRules, true); - } - - /** - * 数据转换 - * - * @param ctxNode - * @param stepContext - * @param fixed optional - * @param mappingRules optional - * @return - */ - public static Map transform(ONode ctxNode, StepContext stepContext, - Map fixed, Map mappingRules, boolean supportMultiLevels) { - try { - if (fixed != null && fixed.containsKey(CommonConstants.WILDCARD_TILDE)) { - Object val = fixed.get(CommonConstants.WILDCARD_TILDE); - fixed = new HashMap<>(); - fixed.put(CommonConstants.WILDCARD_TILDE, val); - } - if (mappingRules != null && mappingRules.containsKey(CommonConstants.WILDCARD_TILDE)) { - Object val = mappingRules.get(CommonConstants.WILDCARD_TILDE); - mappingRules = new HashMap<>(); - mappingRules.put(CommonConstants.WILDCARD_TILDE, val); - } - Map result = new HashMap<>(); - if (fixed != null) { - result.putAll((Map) convertPath(fixed, supportMultiLevels)); - } - if (mappingRules != null) { - // 路径映射 - ONode target = transform(ctxNode, mappingRules, supportMultiLevels); - // 脚本转换 - Map scriptRules = getScriptRules(mappingRules); - Map scriptResult = ScriptHelper.executeScripts(target, scriptRules, ctxNode, stepContext, supportMultiLevels); - if (scriptResult != null && !scriptResult.isEmpty()) { - result = MapUtil.merge(result, scriptResult); - } - } - return result; - }catch(FizzRuntimeException e) { - throw new FizzRuntimeException(e.getMessage(), e, stepContext); - } - } - - public static Map convertPath(Map fixed, boolean supportMultiLevels) { - ONode target = ONode.load(new HashMap()); - if (fixed.isEmpty()) { - return target.toObject(Map.class); - } - - // wildcard star entry - Object starValObj = null; - String starEntryKey = null; - - for (Entry entry : fixed.entrySet()) { - if (CommonConstants.WILDCARD_STAR.equals(entry.getKey())) { - starValObj = entry.getValue(); - starEntryKey = entry.getKey(); - }else { - setByPath(target, entry.getKey(), entry.getValue(), supportMultiLevels); - } - } - if(starEntryKey != null) { - setByPath(target, starEntryKey, starValObj, supportMultiLevels); - } - - return target.toObject(Map.class); - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/RPCInput.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/RPCInput.java deleted file mode 100644 index d676d16..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/RPCInput.java +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import org.apache.logging.log4j.ThreadContext; -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.util.CollectionUtils; - -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.util.Consts; -import com.fizzgate.util.JacksonUtils; - -import reactor.core.publisher.Mono; - -import javax.script.ScriptException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class RPCInput extends Input { - protected static final Logger LOGGER = LoggerFactory.getLogger(RPCInput.class.getName()); - protected static final String FALLBACK_MODE_STOP = "stop"; - protected static final String FALLBACK_MODE_CONTINUE = "continue"; - protected Map request = new ConcurrentHashMap<>(); - protected Map response = new ConcurrentHashMap<>(); - - protected void doRequestMapping(InputConfig aConfig, InputContext inputContext) { - - } - - protected void doOnResponseSuccess(RPCResponse cr, long elapsedMillis) { - - } - protected Mono bodyToMono(RPCResponse cr){ - return cr.getBodyMono(); - } - - protected void doOnBodyError(Throwable ex, long elapsedMillis) { - } - - protected void doOnBodySuccess(Object resp, long elapsedMillis) { - } - - protected void doResponseMapping(InputConfig aConfig, InputContext inputContext, Object responseBody) { - } - - @Override - @SuppressWarnings("unchecked") - public boolean needRun(StepContext stepContext) { - Map condition = ((InputConfig) config).getCondition(); - if (CollectionUtils.isEmpty(condition)) { - // 没有配置condition,直接运行 - return Boolean.TRUE; - } - - ONode ctxNode = PathMapping.toONode(stepContext); - try { - Boolean needRun = ScriptHelper.execute(condition, ctxNode, stepContext, Boolean.class); - return needRun != null ? needRun : Boolean.TRUE; - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(condition), e); - throw new ExecuteScriptException(e, stepContext, condition); - } - } - - protected String prefix; - - @Override - public Mono run() { - long t1 = System.currentTimeMillis(); - this.doRequestMapping(config, inputContext); - inputContext.getStepContext().addElapsedTime(stepResponse.getStepName() + "-" + this.name + "-RequestMapping", - System.currentTimeMillis() - t1); - - prefix = stepResponse.getStepName() + "-" + "调用接口"; - long start = System.currentTimeMillis(); - Mono rpcResponse = this.getClientSpecFromContext(config, inputContext); - Mono body = rpcResponse.flatMap(cr->{ - return Mono.just(cr).doOnError(throwable -> cleanup(cr)); - }).doOnSuccess(cr -> { - long elapsedMillis = System.currentTimeMillis() - start; - this.doOnResponseSuccess(cr, elapsedMillis); - - }).flatMap(cr -> { return this.bodyToMono(cr); }).doOnSuccess(resp -> { - long elapsedMillis = System.currentTimeMillis() - start; - this.doOnBodySuccess(resp, elapsedMillis); - }).doOnError(ex -> { - long elapsedMillis = System.currentTimeMillis() - start; - this.doOnBodyError(ex, elapsedMillis); - }); - - // fallback handler - InputConfig reqConfig = (InputConfig) config; - if (reqConfig.getFallback() != null) { - Map fallback = reqConfig.getFallback(); - String mode = fallback.get("mode"); - if (FALLBACK_MODE_STOP.equals(mode)) { - body = body.onErrorStop(); - } else if (FALLBACK_MODE_CONTINUE.equals(mode)) { - body = body.onErrorResume(ex -> { - return Mono.just(fallback.get("defaultResult")); - }); - } else { - body = body.onErrorStop(); - } - } - - return body.flatMap(item -> { - Map result = new HashMap(); - result.put("data", item); - result.put("request", this); - - long t3 = System.currentTimeMillis(); - this.doResponseMapping(config, inputContext, item); - inputContext.getStepContext().addElapsedTime( - stepResponse.getStepName() + "-" + this.name + "-ResponseMapping", System.currentTimeMillis() - t3); - - return Mono.just(result); - }); - } - - private void cleanup(RPCResponse clientResponse) { - - } - - protected Mono getClientSpecFromContext(InputConfig aConfig, InputContext inputContext) { - return null; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/RPCResponse.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/RPCResponse.java deleted file mode 100644 index 5c5f502..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/RPCResponse.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import org.springframework.util.MultiValueMap; - -import reactor.core.publisher.Mono; - -/** - * - * @author linwaiwai - * - */ -public class RPCResponse { - private MultiValueMap headers; - private Mono bodyMono; - - public MultiValueMap getHeaders() { - return headers; - } - - public void setHeaders(MultiValueMap headers) { - this.headers = headers; - } - - public Mono getBodyMono() { - return bodyMono; - } - - public void setBodyMono(Mono bodyMono) { - this.bodyMono = bodyMono; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/ScriptHelper.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/ScriptHelper.java deleted file mode 100644 index c247e05..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/ScriptHelper.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import javax.script.ScriptException; - -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.exception.RedirectException; -import com.fizzgate.exception.StopAndResponseException; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.util.JacksonUtils; -import com.fizzgate.util.Script; -import com.fizzgate.util.ScriptUtils; - -import org.springframework.util.StringUtils; - -/** - * - * @author Francis Dong - * - */ -public class ScriptHelper { - - private static final Logger LOGGER = LoggerFactory.getLogger(ScriptHelper.class); - - public static Object execute(Map scriptCfg, ONode ctxNode, StepContext stepContext) - throws ScriptException { - return execute(scriptCfg, ctxNode, stepContext, Object.class); - } - - @SuppressWarnings("unchecked") - public static T execute(Map scriptCfg, ONode ctxNode, StepContext stepContext, Class clazz) - throws ScriptException { - Script script = new Script(); - script.setType((String) scriptCfg.get("type")); - script.setSource((String) scriptCfg.get("source")); - if (!StringUtils.hasText(script.getType()) || !StringUtils.hasText(script.getSource())) { - return null; - } - - Map ctx = new HashMap<>(); - ctx.put("context", stepContext); - - Object rs = ScriptUtils.execute(script, ctx); - if (ScriptUtils.GROOVY.equals(script.getType())) { - return (T) handleStopResponse(stepContext, rs); - } else if (ScriptUtils.JAVA_SCRIPT.equals(script.getType())) { - if(rs != null) { - if(rs instanceof Collection || rs instanceof Map) { - return (T) rs; - }else { - String json = rs.toString(); - if(json.startsWith("[") && json.endsWith("]")) { - return JSON.parseArray(json).toJavaObject(clazz); - }else if(json.startsWith("{") && json.endsWith("}")) { - if(clazz.isAssignableFrom(Map.class)) { - return (T)handleStopResponse(stepContext, JSON.parseObject(json).toJavaObject(clazz)); - }else { - handleStopResponse(stepContext, JSON.parseObject(json).toJavaObject(Map.class)); - return JSON.parseObject(json).toJavaObject(clazz); - } - } - } - return (T) rs; - } - return null; - } else { - return (T) rs; - } - } - - public static Map executeScripts(ONode target, Map scriptRules, ONode ctxNode, - StepContext stepContext, boolean supportMultiLevels) { - return executeScripts(target, scriptRules, ctxNode, stepContext, Object.class, supportMultiLevels); - } - - @SuppressWarnings("unchecked") - public static Map executeScripts(ONode target, Map scriptRules, ONode ctxNode, - StepContext stepContext, Class clazz, boolean supportMultiLevels) { - if(target == null) { - target = ONode.load(new HashMap()); - } - if (scriptRules != null && !scriptRules.isEmpty()) { - // wildcard star entry - Object starValObj = null; - String starEntryKey = null; - for (Entry entry : scriptRules.entrySet()) { - Map scriptCfg = (Map) entry.getValue(); - try { - if (CommonConstants.WILDCARD_STAR.equals(entry.getKey())) { - starValObj = execute(scriptCfg, ctxNode, stepContext, clazz); - starEntryKey = entry.getKey(); - }else { - PathMapping.setByPath(target, entry.getKey(), execute(scriptCfg, ctxNode, stepContext, clazz), supportMultiLevels); - } - } catch (ScriptException e) { - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - if(starEntryKey != null) { - PathMapping.setByPath(target, starEntryKey, starValObj, supportMultiLevels); - } - } - return target.toObject(Map.class); - } - - public static Object handleStopResponse(StepContext stepContext, Object result) { - if(result instanceof Map) { - Map rs = (Map) result; - if (rs.containsKey(CommonConstants.STOP_AND_RESPONSE_KEY)) { - if (rs.get(CommonConstants.STOP_AND_RESPONSE_KEY) != null - && rs.get(CommonConstants.STOP_AND_RESPONSE_KEY) instanceof Boolean - && (Boolean) rs.get(CommonConstants.STOP_AND_RESPONSE_KEY)) { - rs.remove(CommonConstants.STOP_AND_RESPONSE_KEY); - - // redirect - if(rs.get(CommonConstants.REDIRECT_URL_KEY) != null) { - throw new RedirectException("stop and redirect", String.valueOf(rs.get(CommonConstants.REDIRECT_URL_KEY))); - } - - // 测试模式返回StepContext - if (stepContext.returnContext()) { - rs.put(stepContext.CONTEXT_FIELD, stepContext); - } - - // exception - throw new StopAndResponseException("stop and response", JSON.toJSONString(rs)); - } else { - rs.remove(CommonConstants.STOP_AND_RESPONSE_KEY); - } - } - } - return result; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboInput.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboInput.java deleted file mode 100644 index 8b772cc..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboInput.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.dubbo; - -import org.apache.logging.log4j.ThreadContext; -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.CollectionUtils; - -import com.fizzgate.FizzAppContext; -import com.fizzgate.config.SystemConfig; -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.input.*; -import com.fizzgate.proxy.dubbo.ApacheDubboGenericService; -import com.fizzgate.proxy.dubbo.DubboInterfaceDeclaration; -import com.fizzgate.util.Consts; -import com.fizzgate.util.JacksonUtils; - -import reactor.core.publisher.Mono; -import reactor.util.retry.Retry; - -import javax.script.ScriptException; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class DubboInput extends RPCInput { - static public InputType TYPE = new InputType("DUBBO"); - private static final Logger LOGGER = LoggerFactory.getLogger(DubboInput.class); - - @SuppressWarnings("unchecked") - @Override - protected Mono getClientSpecFromContext(InputConfig aConfig, InputContext inputContext) { - DubboInputConfig config = (DubboInputConfig) aConfig; - - int timeout = config.getTimeout() < 1 ? 10000 : config.getTimeout() > 30000 ? 30000 : config.getTimeout(); - long numRetries = config.getNumRetries() > 0 ? config.getNumRetries() : 0; - long retryInterval = config.getRetryInterval() > 0 ? config.getRetryInterval() : 0; - Map attachments = (Map) request.get("attachments"); - ConfigurableApplicationContext applicationContext = this.getCurrentApplicationContext(); - Map body = (Map) request.get("body"); - - ApacheDubboGenericService proxy = applicationContext.getBean(ApacheDubboGenericService.class); - DubboInterfaceDeclaration declaration = new DubboInterfaceDeclaration(); - declaration.setServiceName(config.getServiceName()); - declaration.setVersion(config.getVersion()); - declaration.setGroup(config.getGroup()); - declaration.setMethod(config.getMethod()); - declaration.setParameterTypes(config.getParamTypes()); - declaration.setTimeout(timeout); - HashMap contextAttachment = null; - if (attachments == null) { - contextAttachment = new HashMap(); - } else { - contextAttachment = new HashMap(attachments); - } - if (inputContext.getStepContext() != null && inputContext.getStepContext().getTraceId() != null) { - if (FizzAppContext.appContext == null) { - contextAttachment.put(CommonConstants.HEADER_TRACE_ID, inputContext.getStepContext().getTraceId()); - } else { - SystemConfig systemConfig = FizzAppContext.appContext.getBean(SystemConfig.class); - contextAttachment.put(systemConfig.fizzTraceIdHeader(), inputContext.getStepContext().getTraceId()); - } - } - - HashMap contextAttachment2 = contextAttachment; - Mono proxyResponse = Mono.just("").flatMap(s -> { - return proxy.send(body, declaration, contextAttachment2); - }); - return proxyResponse.retryWhen(Retry.fixedDelay(numRetries, Duration.ofMillis(retryInterval)) - .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { - throw new FizzRuntimeException("External Dubbo Service failed to process after max retries"); - })).flatMap(cr -> { - DubboRPCResponse response = new DubboRPCResponse(); - response.setBodyMono(Mono.just(cr)); - return Mono.just(response); - }); - } - - protected void doRequestMapping(InputConfig aConfig, InputContext inputContext) { - DubboInputConfig config = (DubboInputConfig) aConfig; - - // 把请求信息放入stepContext - Map group = new HashMap<>(); - group.put("request", request); - group.put("response", response); - this.stepResponse.addRequest(name, group); - - request.put("serviceName", config.getServiceName()); - request.put("version", config.getVersion()); - request.put("group", config.getGroup()); - request.put("method", config.getMethod()); - request.put("paramTypes", config.getParamTypes()); - - // 数据转换 - if (inputContext != null && inputContext.getStepContext() != null) { - StepContext stepContext = inputContext.getStepContext(); - Map dataMapping = this.getConfig().getDataMapping(); - if (dataMapping != null) { - Map requestMapping = (Map) dataMapping.get("request"); - if (!CollectionUtils.isEmpty(requestMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - - // attachments - Map attachments = PathMapping.transform(ctxNode, stepContext, - (Map) requestMapping.get("fixedHeaders"), - (Map) requestMapping.get("headers")); - if (attachments.containsKey(CommonConstants.WILDCARD_TILDE) - && attachments.get(CommonConstants.WILDCARD_TILDE) instanceof Map) { - request.put("attachments", attachments.get(CommonConstants.WILDCARD_TILDE)); - } else { - request.put("attachments", attachments); - } - - // body - Map body = PathMapping.transform(ctxNode, stepContext, - (Map) requestMapping.get("fixedBody"), - (Map) requestMapping.get("body")); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - request.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (requestMapping.get("script") != null) { - Map scriptCfg = (Map) requestMapping.get("script"); - try { - Object reqBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if (reqBody != null) { - body.putAll((Map) reqBody); - } - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - request.put("body", body); - } - } - } - } - } - - protected void doOnResponseSuccess(RPCResponse cr, long elapsedMillis) { - inputContext.getStepContext().addElapsedTime(this.getApiName(), elapsedMillis); - } - - protected Mono bodyToMono(RPCResponse cr) { - return cr.getBodyMono(); - } - - protected void doOnBodyError(Throwable ex, long elapsedMillis) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("failed to call {}", this.getApiName(), ex); - inputContext.getStepContext().addElapsedTime(this.getApiName() + " failed ", elapsedMillis); - } - - protected void doOnBodySuccess(Object resp, long elapsedMillis) { - - } - - protected void doResponseMapping(InputConfig aConfig, InputContext inputContext, Object responseBody) { - DubboInputConfig config = (DubboInputConfig) aConfig; - response.put("body", responseBody); - - // 数据转换 - if (inputContext != null && inputContext.getStepContext() != null) { - StepContext stepContext = inputContext.getStepContext(); - Map dataMapping = this.getConfig().getDataMapping(); - if (dataMapping != null) { - Map responseMapping = (Map) dataMapping.get("response"); - if (!CollectionUtils.isEmpty(responseMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - - // body - Map fixedBody = (Map) responseMapping.get("fixedBody"); - Map bodyMapping = (Map) responseMapping.get("body"); - Map scriptCfg = (Map) responseMapping.get("script"); - if ((fixedBody != null && !fixedBody.isEmpty()) || (bodyMapping != null && !bodyMapping.isEmpty()) - || (scriptCfg != null && scriptCfg.get("type") != null - && scriptCfg.get("source") != null)) { - // body - Map body = new HashMap<>(); - body.putAll(PathMapping.transform(ctxNode, stepContext, fixedBody, bodyMapping)); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - response.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (scriptCfg != null && scriptCfg.get("type") != null && scriptCfg.get("source") != null) { - try { - Object respBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if (respBody != null) { - body.putAll((Map) respBody); - } - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - response.put("body", body); - } - } - } - } else { - response.put("body", responseBody); - } - } - } - - public static Class inputConfigClass() { - return DubboInputConfig.class; - } - - private String getApiName() { - return prefix + " - " + request.get("serviceName") + " - " + request.get("method"); - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboInputConfig.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboInputConfig.java deleted file mode 100644 index d3a3b7b..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboInputConfig.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.input.extension.dubbo; - -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.input.InputConfig; - -/** -* -* @author linwaiwai -* @author Francis Dong -* -*/ -public class DubboInputConfig extends InputConfig { - private String serviceName; - private String version; - private String group; - private String method; - private String paramTypes; - private int timeout; - private long numRetries; - /** - * retry interval in millisecond - */ - private long retryInterval; - - public DubboInputConfig(Map configMap) { - super(configMap); - } - - public void parse() { - String serviceName = (String) configMap.get("serviceName"); - if (StringUtils.isBlank(serviceName)) { - throw new FizzRuntimeException("service name can not be blank"); - } - setServiceName(serviceName); - - String version = (String) configMap.get("version"); - if (!StringUtils.isBlank(version)) { - setVersion(version); - } - - String group = (String) configMap.get("group"); - if (!StringUtils.isBlank(group)) { - setGroup(group); - } - - String method = (String) configMap.get("method"); - if (StringUtils.isBlank(method)) { - throw new FizzRuntimeException("method can not be blank"); - } - setMethod(method); - String paramTypes = (String) configMap.get("paramTypes"); - if (!StringUtils.isBlank(paramTypes)) { - setParamTypes(paramTypes); - } - - if (configMap.get("timeout") != null && StringUtils.isNotBlank(configMap.get("timeout").toString())) { - try { - setTimeout(Integer.valueOf(configMap.get("timeout").toString())); - } catch (Exception e) { - throw new RuntimeException("invalid timeout: " + configMap.get("timeout").toString() + " " + e.getMessage(), e); - } - } - if (configMap.get("numRetries") != null && StringUtils.isNotBlank(configMap.get("numRetries").toString())) { - try { - numRetries = Long.valueOf(configMap.get("numRetries").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid numRetries: " + configMap.get("numRetries").toString() + " " + e.getMessage(), e); - } - } - if (configMap.get("retryInterval") != null && StringUtils.isNotBlank(configMap.get("retryInterval").toString())) { - try { - retryInterval = Long.valueOf(configMap.get("retryInterval").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid retryInterval: " + configMap.get("retryInterval").toString() + " " + e.getMessage(), e); - } - } - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getGroup() { - return group; - } - - public void setGroup(String group) { - this.group = group; - } - - public String getParamTypes() { - return paramTypes; - } - - public void setParamTypes(String paramTypes) { - this.paramTypes = paramTypes; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public void setMethod(String method) { - this.method = method; - } - - public String getServiceName() { - return serviceName; - } - - public String getMethod() { - return method; - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public long getNumRetries() { - return numRetries; - } - - public void setNumRetries(long numRetries) { - this.numRetries = numRetries; - } - - public long getRetryInterval() { - return retryInterval; - } - - public void setRetryInterval(long retryInterval) { - this.retryInterval = retryInterval; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboRPCResponse.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboRPCResponse.java deleted file mode 100644 index a1f5a1a..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/dubbo/DubboRPCResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.dubbo; - -import com.fizzgate.fizz.input.RPCResponse; - -/** -* -* @author linwaiwai -* -*/ -public class DubboRPCResponse extends RPCResponse { -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GRPCResponse.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GRPCResponse.java deleted file mode 100644 index a58d703..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GRPCResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.grpc; - -import org.springframework.http.HttpStatus; - -import com.fizzgate.fizz.input.RPCResponse; - -/** - * - * @author linwaiwai - * - */ -public class GRPCResponse extends RPCResponse { - private HttpStatus statusCode; - public void setStatus(HttpStatus statusCode) { - this.statusCode = statusCode; - } - - public HttpStatus getStatusCode() { - return statusCode; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GrpcInput.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GrpcInput.java deleted file mode 100644 index 9af9e11..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GrpcInput.java +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.grpc; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.FizzAppContext; -import com.fizzgate.config.SystemConfig; -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.input.*; -import com.fizzgate.proxy.grpc.GrpcGenericService; -import com.fizzgate.proxy.grpc.GrpcInstanceService; -import com.fizzgate.proxy.grpc.GrpcInterfaceDeclaration; -import com.fizzgate.util.Consts; -import com.fizzgate.util.JacksonUtils; - -import org.apache.logging.log4j.ThreadContext; -import org.noear.snack.ONode; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.util.CollectionUtils; -import reactor.core.publisher.Mono; -import reactor.util.retry.Retry; - -import javax.script.ScriptException; -import java.time.Duration; -import java.util.HashMap; -import java.util.Map; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class GrpcInput extends RPCInput implements IInput { - static public InputType TYPE = new InputType("GRPC"); - - @SuppressWarnings("unchecked") - @Override - protected Mono getClientSpecFromContext(InputConfig aConfig, InputContext inputContext) { - GrpcInputConfig config = (GrpcInputConfig) aConfig; - - int timeout = config.getTimeout() < 1 ? 10000 : config.getTimeout() > 30000 ? 30000 : config.getTimeout(); - long numRetries = config.getNumRetries() > 0 ? config.getNumRetries() : 0; - long retryInterval = config.getRetryInterval() > 0 ? config.getRetryInterval() : 0; - Map attachments = (Map) request.get("attachments"); - ConfigurableApplicationContext applicationContext = this.getCurrentApplicationContext(); - Map body = (Map) request.get("body"); - String endpoint = (String) request.get("endpoint"); - - GrpcGenericService proxy = applicationContext.getBean(GrpcGenericService.class); - GrpcInterfaceDeclaration declaration = new GrpcInterfaceDeclaration(); - declaration.setEndpoint(endpoint); - declaration.setServiceName(config.getServiceName()); - declaration.setMethod(config.getMethod()); - declaration.setTimeout(timeout); - HashMap contextAttachment = null; - if (attachments == null) { - contextAttachment = new HashMap(); - } else { - contextAttachment = new HashMap(attachments); - } - if (inputContext.getStepContext() != null && inputContext.getStepContext().getTraceId() != null) { - if (FizzAppContext.appContext == null) { - contextAttachment.put(CommonConstants.HEADER_TRACE_ID, inputContext.getStepContext().getTraceId()); - } else { - SystemConfig systemConfig = FizzAppContext.appContext.getBean(SystemConfig.class); - contextAttachment.put(systemConfig.fizzTraceIdHeader(), inputContext.getStepContext().getTraceId()); - } - } - - HashMap contextAttachment2 = contextAttachment; - Mono proxyResponse = Mono.just("").flatMap(s -> { - return proxy.send(JSON.toJSONString(body), declaration, contextAttachment2); - }); - return proxyResponse.retryWhen(Retry.fixedDelay(numRetries, Duration.ofMillis(retryInterval)) - .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { - throw new FizzRuntimeException("External gRPC Service failed to process after max retries"); - })).flatMap(cr -> { - GRPCResponse response = new GRPCResponse(); - response.setBodyMono(Mono.just(cr)); - return Mono.just(response); - }); - } - - @SuppressWarnings("unchecked") - protected void doRequestMapping(InputConfig aConfig, InputContext inputContext) { - GrpcInputConfig config = (GrpcInputConfig) aConfig; - - // 把请求信息放入stepContext - Map group = new HashMap<>(); - group.put("request", request); - group.put("response", response); - this.stepResponse.addRequest(name, group); - - request.put("serviceName", config.getServiceName()); - request.put("method", config.getMethod()); - GrpcInstanceService grpcInstanceService = this.getCurrentApplicationContext() - .getBean(GrpcInstanceService.class); - request.put("endpoint", grpcInstanceService.getInstance(config.getServiceName())); - - // 数据转换 - if (inputContext != null && inputContext.getStepContext() != null) { - StepContext stepContext = inputContext.getStepContext(); - Map dataMapping = this.getConfig().getDataMapping(); - if (dataMapping != null) { - Map requestMapping = (Map) dataMapping.get("request"); - if (!CollectionUtils.isEmpty(requestMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - - // attachments - Map attachments = PathMapping.transform(ctxNode, stepContext, - (Map) requestMapping.get("fixedHeaders"), - (Map) requestMapping.get("headers")); - if (attachments.containsKey(CommonConstants.WILDCARD_TILDE) - && attachments.get(CommonConstants.WILDCARD_TILDE) instanceof Map) { - request.put("attachments", attachments.get(CommonConstants.WILDCARD_TILDE)); - } else { - request.put("attachments", attachments); - } - - // body - Map body = PathMapping.transform(ctxNode, stepContext, - (Map) requestMapping.get("fixedBody"), - (Map) requestMapping.get("body")); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - request.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (requestMapping.get("script") != null) { - Map scriptCfg = (Map) requestMapping.get("script"); - try { - Object reqBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if (reqBody != null) { - body.putAll((Map) reqBody); - } - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - request.put("body", body); - } - } - } - } - } - - protected void doOnResponseSuccess(RPCResponse cr, long elapsedMillis) { - inputContext.getStepContext().addElapsedTime(this.getApiName(), elapsedMillis); - } - - protected Mono bodyToMono(RPCResponse cr) { - return cr.getBodyMono(); - } - - protected void doOnBodyError(Throwable ex, long elapsedMillis) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("failed to call {}", this.getApiName(), ex); - inputContext.getStepContext().addElapsedTime(this.getApiName() + " failed ", elapsedMillis); - } - - protected void doOnBodySuccess(Object resp, long elapsedMillis) { - - } - - @SuppressWarnings("unchecked") - protected void doResponseMapping(InputConfig aConfig, InputContext inputContext, Object responseBody) { -// GrpcInputConfig config = (GrpcInputConfig) aConfig; - response.put("body", responseBody); - - // 数据转换 - if (inputContext != null && inputContext.getStepContext() != null) { - StepContext stepContext = inputContext.getStepContext(); - Map dataMapping = this.getConfig().getDataMapping(); - if (dataMapping != null) { - Map responseMapping = (Map) dataMapping.get("response"); - if (!CollectionUtils.isEmpty(responseMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - - // body - Map fixedBody = (Map) responseMapping.get("fixedBody"); - Map bodyMapping = (Map) responseMapping.get("body"); - Map scriptCfg = (Map) responseMapping.get("script"); - if ((fixedBody != null && !fixedBody.isEmpty()) || (bodyMapping != null && !bodyMapping.isEmpty()) - || (scriptCfg != null && scriptCfg.get("type") != null - && scriptCfg.get("source") != null)) { - // body - Map body = new HashMap<>(); - body.putAll(PathMapping.transform(ctxNode, stepContext, fixedBody, bodyMapping)); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - response.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (scriptCfg != null && scriptCfg.get("type") != null && scriptCfg.get("source") != null) { - try { - Object respBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if (respBody != null) { - body.putAll((Map) respBody); - } - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), - e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - response.put("body", body); - } - } - } - } else { - response.put("body", responseBody); - } - } - } - - private String getApiName() { - return prefix + " - " + request.get("serviceName") + " - " + request.get("method"); - } - - public static Class inputConfigClass() { - return GrpcInputConfig.class; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GrpcInputConfig.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GrpcInputConfig.java deleted file mode 100644 index fda7382..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/grpc/GrpcInputConfig.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.grpc; - -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; - -import com.fizzgate.fizz.exception.FizzRuntimeException; -import com.fizzgate.fizz.input.InputConfig; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class GrpcInputConfig extends InputConfig { - - private int timeout; - private String serviceName; - private String method; - private long numRetries; - /** - * retry interval in millisecond - */ - private long retryInterval; - - public GrpcInputConfig(Map configMap) { - super(configMap); - } - - public void parse() { - String serviceName = (String) configMap.get("serviceName"); - if (StringUtils.isBlank(serviceName)) { - throw new FizzRuntimeException("service name can not be blank"); - } - setServiceName(serviceName); - - String method = (String) configMap.get("method"); - if (StringUtils.isBlank(method)) { - throw new FizzRuntimeException("method can not be blank"); - } - setMethod(method); - - if (configMap.get("timeout") != null && StringUtils.isNotBlank(configMap.get("timeout").toString())) { - try { - setTimeout(Integer.valueOf(configMap.get("timeout").toString())); - } catch (Exception e) { - throw new RuntimeException("invalid timeout: " + configMap.get("timeout").toString() + " " + e.getMessage(), e); - } - } - if (configMap.get("numRetries") != null && StringUtils.isNotBlank(configMap.get("numRetries").toString())) { - try { - numRetries = Long.valueOf(configMap.get("numRetries").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid numRetries: " + configMap.get("numRetries").toString() + " " + e.getMessage(), e); - } - } - if (configMap.get("retryInterval") != null && StringUtils.isNotBlank(configMap.get("retryInterval").toString())) { - try { - retryInterval = Long.valueOf(configMap.get("retryInterval").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid retryInterval: " + configMap.get("retryInterval").toString() + " " + e.getMessage(), e); - } - } - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public String getMethod() { - return method; - } - - public void setMethod(String method) { - this.method = method; - } - - public long getNumRetries() { - return numRetries; - } - - public void setNumRetries(long numRetries) { - this.numRetries = numRetries; - } - - public long getRetryInterval() { - return retryInterval; - } - - public void setRetryInterval(long retryInterval) { - this.retryInterval = retryInterval; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestInput.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestInput.java deleted file mode 100644 index bd6adc7..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestInput.java +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.request; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.config.SystemConfig; -import com.fizzgate.constants.CommonConstants; -import com.fizzgate.exception.ExecuteScriptException; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.StepResponse; -import com.fizzgate.fizz.input.*; -import com.fizzgate.proxy.FizzWebClient; -import com.fizzgate.proxy.http.HttpInstanceService; -import com.fizzgate.service_registry.RegistryCenterService; -import com.fizzgate.util.Consts; -import com.fizzgate.util.JacksonUtils; -import com.fizzgate.util.MapUtil; -import com.fizzgate.util.TypeUtils; -import com.fizzgate.xml.JsonToXml; -import com.fizzgate.xml.XmlToJson; -import com.fizzgate.xml.XmlToJson.Builder; - -import org.apache.commons.lang3.StringUtils; -import org.apache.logging.log4j.ThreadContext; -import org.noear.snack.ONode; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.util.CollectionUtils; -import org.springframework.util.MultiValueMap; -import org.springframework.web.reactive.function.BodyInserters; -import org.springframework.web.reactive.function.client.ClientResponse; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; -import reactor.core.publisher.Mono; - -import javax.script.ScriptException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -@SuppressWarnings("unchecked") -public class RequestInput extends RPCInput implements IInput{ - - private static final Logger LOGGER = LoggerFactory.getLogger(RequestInput.class); - static public InputType TYPE = new InputType("REQUEST"); - private InputType type; - protected Map dataMapping; - - private static final String CONTENT_TYPE_JSON = "application/json"; - private static final String CONTENT_TYPE_XML = "application/xml"; - private static final String CONTENT_TYPE_TEXT_XML = "text/xml"; - private static final String CONTENT_TYPE_JS = "application/javascript"; - private static final String CONTENT_TYPE_HTML = "text/html"; - private static final String CONTENT_TYPE_TEXT = "text/plain"; - private static final String CONTENT_TYPE_AUTO = "auto"; - private static final String CONTENT_TYPE_MULTIPART_FORM_DATA = "multipart/form-data"; - private static final String CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded"; - - private static final String CONTENT_TYPE = "content-type"; - - private static final Integer SERVICE_TYPE_DISCOVERY = 1; - private static final Integer SERVICE_TYPE_HTTP = 2; - - private String respContentType; - private String reqContentType; - - private String[] xmlArrPaths; - - private static Pattern PATH_VAR_PATTERN = Pattern.compile("(\\{)([^/]*)(\\})"); - - public InputType getType() { - return type; - } - - public void setType(InputType typeEnum) { - this.type = typeEnum; - } - - public Map getDataMapping() { - return dataMapping; - } - - public void setDataMapping(Map dataMapping) { - this.dataMapping = dataMapping; - } - - protected void doRequestMapping(InputConfig aConfig, InputContext inputContext) { - RequestInputConfig config = (RequestInputConfig) aConfig; - - Map params = new HashMap<>(); - synchronized (inputContext.getStepContext()) { - // 把请求信息放入stepContext - Map group = new HashMap<>(); - group.put("request", request); - group.put("response", response); - this.stepResponse.addRequest(name, group); - - HttpMethod method = HttpMethod.valueOf(config.getMethod().toUpperCase()); - request.put("method", method); - - params.putAll(MapUtil.toHashMap(config.getQueryParams())); - request.put("params", params); - } - - ONode ctxNode = null; - // 数据转换 - if (inputContext != null && inputContext.getStepContext() != null) { - StepContext stepContext = inputContext.getStepContext(); - ctxNode = PathMapping.toONode(stepContext); - synchronized (stepContext) { - Map dataMapping = this.getConfig().getDataMapping(); - if (dataMapping != null) { - Map requestMapping = (Map) dataMapping.get("request"); - if (!CollectionUtils.isEmpty(requestMapping)) { - reqContentType = (String) requestMapping.get("contentType"); - - // headers - Map headers = PathMapping.transform(ctxNode, stepContext, - MapUtil.upperCaseKey(MapUtil.list2Map(requestMapping.get("fixedHeaders"))), - MapUtil.upperCaseKey(MapUtil.list2Map(requestMapping.get("headers"))), false); - if (headers.containsKey(CommonConstants.WILDCARD_TILDE) - && headers.get(CommonConstants.WILDCARD_TILDE) instanceof Map) { - request.put("headers", headers.get(CommonConstants.WILDCARD_TILDE)); - } else { - request.put("headers", headers); - } - - // params - params.putAll(PathMapping.transform(ctxNode, stepContext, - MapUtil.list2Map(requestMapping.get("fixedParams")), - MapUtil.list2Map(requestMapping.get("params")), false)); - if (params.containsKey(CommonConstants.WILDCARD_TILDE) - && params.get(CommonConstants.WILDCARD_TILDE) instanceof Map) { - request.put("params", params.get(CommonConstants.WILDCARD_TILDE)); - } else { - request.put("params", params); - } - - // body - boolean supportMultiLevels = true; - if (CONTENT_TYPE_MULTIPART_FORM_DATA.equals(reqContentType) || - CONTENT_TYPE_FORM_URLENCODED.equals(reqContentType)) { - supportMultiLevels = false; - } - Map body = PathMapping.transform(ctxNode, stepContext, - MapUtil.list2Map(requestMapping.get("fixedBody")), - MapUtil.list2Map(requestMapping.get("body")), supportMultiLevels); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - request.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (requestMapping.get("script") != null) { - Map scriptCfg = (Map) requestMapping.get("script"); - try { - Object reqBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if (reqBody != null) { - body.putAll((Map) reqBody); - } - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - request.put("body", body); - } - } - } - } - } - - if (config.isNewVersion()) { - String host = config.getServiceName(); - - if (SERVICE_TYPE_HTTP.equals(config.getServiceType().intValue())) { - HttpInstanceService httpInstanceService = this.getCurrentApplicationContext() - .getBean(HttpInstanceService.class); - String instance = httpInstanceService.getInstance(config.getServiceName()); - if (instance != null) { - host = instance; - } - } else if (SERVICE_TYPE_DISCOVERY.equals(config.getServiceType())) { - if (StringUtils.isNotBlank(config.getRegistryName())) { - // support choosing registry center - host = RegistryCenterService.getServiceNameSpace(config.getRegistryName(), host); - } - } - StringBuffer sb = new StringBuffer(); - sb.append(config.getProtocol()).append("://").append(host) - .append(config.getPath().startsWith("/") ? "" : "/").append(setPathVariable(ctxNode, config.getPath())); - - UriComponents uriComponents = UriComponentsBuilder.fromUriString(sb.toString()) - .queryParams(MapUtil.toMultiValueMap(params)).build(); - - synchronized (inputContext.getStepContext()) { - request.put("url", uriComponents.toUriString()); - } - } else { - UriComponents uriComponents = UriComponentsBuilder.fromUriString(config.getBaseUrl() + setPathVariable(ctxNode, config.getPath())) - .queryParams(MapUtil.toMultiValueMap(params)).build(); - synchronized (inputContext.getStepContext()) { - request.put("url", uriComponents.toUriString()); - } - } - } - - private String setPathVariable(ONode ctxNode, String path) { - if (ctxNode == null || StringUtils.isBlank(path)) { - return path; - } - String[] paths = path.split("/"); - for (int i = 0; i < paths.length; i++) { - Matcher matcher = PATH_VAR_PATTERN.matcher(paths[i]); - if (matcher.find()) { - String jsonPath = matcher.group(2); - Object val = PathMapping.getValueByPath(ctxNode, jsonPath); - if (val != null && !(val instanceof Map) && !(val instanceof List)) { - paths[i] = matcher.replaceAll(String.valueOf(val)); - } - } - } - return String.join("/", paths); - } - - @Override - public void doResponseMapping(InputConfig aConfig, InputContext inputContext, Object responseBody) { - - RequestInputConfig config = (RequestInputConfig) aConfig; - String cfgContentType = null; - Map dataMapping = config.getDataMapping(); - Map responseMapping = null; - if (dataMapping != null) { - responseMapping = (Map) dataMapping.get("response"); - if (!CollectionUtils.isEmpty(responseMapping)) { - cfgContentType = (String) responseMapping.get("contentType"); - String paths = (String) responseMapping.get("xmlArrPaths"); - if (StringUtils.isNotBlank(paths)) { - xmlArrPaths = paths.split(","); - } - } - } - - String ct = null; - if (cfgContentType == null || CONTENT_TYPE_AUTO.equals(cfgContentType)) { - ct = this.respContentType; - } else { - ct = cfgContentType; - } - if (StringUtils.isBlank(ct)) { - ct = CONTENT_TYPE_JSON; - } - - synchronized (inputContext.getStepContext()) { - response.put("body", this.parseBody(ct, (String)responseBody)); - } - - // 数据转换 - if (inputContext != null && inputContext.getStepContext() != null) { - StepContext stepContext = inputContext.getStepContext(); - if (!CollectionUtils.isEmpty(responseMapping)) { - ONode ctxNode = PathMapping.toONode(stepContext); - synchronized (stepContext) { - // headers - Map fixedHeaders = MapUtil.upperCaseKey((Map) responseMapping.get("fixedHeaders")); - Map headerMapping = MapUtil.upperCaseKey((Map) responseMapping.get("headers")); - if ((fixedHeaders != null && !fixedHeaders.isEmpty()) - || (headerMapping != null && !headerMapping.isEmpty())) { - Map headers = new HashMap<>(); - headers.putAll(PathMapping.transform(ctxNode, stepContext, fixedHeaders, headerMapping, false)); - if (headers.containsKey(CommonConstants.WILDCARD_TILDE) - && headers.get(CommonConstants.WILDCARD_TILDE) instanceof Map) { - response.put("headers", headers.get(CommonConstants.WILDCARD_TILDE)); - } else { - response.put("headers", headers); - } - } - - // body - Map fixedBody = (Map) responseMapping.get("fixedBody"); - Map bodyMapping = (Map) responseMapping.get("body"); - Map scriptCfg = (Map) responseMapping.get("script"); - if ((fixedBody != null && !fixedBody.isEmpty()) || (bodyMapping != null && !bodyMapping.isEmpty()) - || (scriptCfg != null && scriptCfg.get("type") != null - && scriptCfg.get("source") != null)) { - // body - Map body = new HashMap<>(); - body.putAll(PathMapping.transform(ctxNode, stepContext, fixedBody, bodyMapping)); - if (body.containsKey(CommonConstants.WILDCARD_TILDE)) { - response.put("body", body.get(CommonConstants.WILDCARD_TILDE)); - } else { - // script - if (scriptCfg != null && scriptCfg.get("type") != null && scriptCfg.get("source") != null) { - try { - Object respBody = ScriptHelper.execute(scriptCfg, ctxNode, stepContext); - if (respBody != null) { - body.putAll((Map) respBody); - } - } catch (ScriptException e) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("execute script failed, {}", JacksonUtils.writeValueAsString(scriptCfg), e); - throw new ExecuteScriptException(e, stepContext, scriptCfg); - } - } - response.put("body", body); - } - } - } - } - } - } - - @Override - protected Mono getClientSpecFromContext(InputConfig aConfig, InputContext inputContext) { - RequestInputConfig config = (RequestInputConfig) aConfig; - - int timeout = config.getTimeout() < 1 ? 10000 : config.getTimeout() > 30000 ? 30000 : config.getTimeout(); - long numRetries = config.getNumRetries() > 0 ? config.getNumRetries() : 0; - long retryInterval = config.getRetryInterval() > 0 ? config.getRetryInterval() : 0; - - HttpMethod method = HttpMethod.valueOf(config.getMethod()); - String url = (String) request.get("url"); - - Map hds = (Map) request.get("headers"); - if (hds == null) { - hds = new HashMap<>(); - } - HttpHeaders headers = MapUtil.toHttpHeaders(hds); - - // default content-type - if (!headers.containsKey(CommonConstants.HEADER_CONTENT_TYPE)) { - if (CONTENT_TYPE_XML.equals(reqContentType) || CONTENT_TYPE_TEXT_XML.equals(reqContentType)) { - headers.add(CommonConstants.HEADER_CONTENT_TYPE, CONTENT_TYPE_XML); - } else if (CONTENT_TYPE_MULTIPART_FORM_DATA.equals(reqContentType)) { - headers.add(CommonConstants.HEADER_CONTENT_TYPE, CONTENT_TYPE_MULTIPART_FORM_DATA); - } else if (CONTENT_TYPE_FORM_URLENCODED.equals(reqContentType)) { - headers.add(CommonConstants.HEADER_CONTENT_TYPE, CONTENT_TYPE_FORM_URLENCODED); - } else { - headers.add(CommonConstants.HEADER_CONTENT_TYPE, CommonConstants.CONTENT_TYPE_JSON); - } - } - - // add default headers - SystemConfig systemConfig = this.getCurrentApplicationContext().getBean(SystemConfig.class); - for (String hdr : systemConfig.getProxySetHeaders()) { - if(inputContext.getStepContext().getInputReqHeader(hdr) != null && !headers.containsKey(hdr)) { - Object o = inputContext.getStepContext().getInputReqHeader(hdr); - if (o instanceof String) { - headers.add(hdr, (String) o); - } else if (o instanceof List){ - List list = (List) o; - List vals = new ArrayList<>(); - for (Object item : list) { - if (item != null) { - vals.add(item.toString()); - } - } - headers.addAll(hdr, vals); - } - } - } - - headers.remove(CommonConstants.HEADER_CONTENT_LENGTH); - headers.add(systemConfig.fizzTraceIdHeader(), inputContext.getStepContext().getTraceId()); - synchronized (inputContext.getStepContext()) { - request.put("headers", MapUtil.headerToHashMap(headers)); - } - - Object body = null; - if (CONTENT_TYPE_XML.equals(reqContentType) || CONTENT_TYPE_TEXT_XML.equals(reqContentType)) { - // convert JSON to XML if it is XML content type - synchronized (inputContext.getStepContext()) { - request.put("jsonBody", request.get("body")); - } - String jsonStr = null; - if (TypeUtils.isBasicType(request.get("body"))) { - jsonStr = request.get("body").toString(); - } else { - jsonStr = JSON.toJSONString(request.get("body")); - } - LOGGER.info("jsonBody={}", jsonStr); - if (jsonStr.startsWith("{") || jsonStr.startsWith("[")) { - JsonToXml jsonToXml = new JsonToXml.Builder(jsonStr).build(); - body = jsonToXml.toString(); - } else { - body = jsonStr; - } - synchronized (inputContext.getStepContext()) { - request.put("body", body); - } - LOGGER.info("body={}", body); - LOGGER.info("headers={}", JSON.toJSONString(headers)); - } else if (CONTENT_TYPE_MULTIPART_FORM_DATA.equals(reqContentType)) { - MultiValueMap mpDataMap = MapUtil - .toMultipartDataMap((Map) request.get("body")); - MapUtil.replaceWithFilePart(mpDataMap, CommonConstants.FILE_KEY_PREFIX, - inputContext.getStepContext().getFilePartMap()); - body = BodyInserters.fromMultipartData(mpDataMap); - } else if (CONTENT_TYPE_FORM_URLENCODED.equals(reqContentType)) { - body = BodyInserters.fromFormData(MapUtil.toMultiValueMap((Map) request.get("body"))); - } else { - if (TypeUtils.isBasicType(request.get("body"))) { - body = request.get("body").toString(); - } else { - body = JSON.toJSONString(request.get("body")); - } - } - - HttpMethod aggrMethod = HttpMethod.valueOf(inputContext.getStepContext().getInputReqAttr("method").toString()); - String aggrPath = (String)inputContext.getStepContext().getInputReqAttr("path"); - String aggrService = aggrPath.split("\\/")[2]; - - FizzWebClient client = this.getCurrentApplicationContext().getBean(FizzWebClient.class); - // Mono clientResponse = client.aggrSend(aggrService, aggrMethod, aggrPath, null, method, url, - // headers, body, (long)timeout); - - Mono clientResponse = client.send(inputContext.getStepContext().getTraceId(), method, url, - headers, body, (long)timeout, numRetries, retryInterval); - return clientResponse.flatMap(cr->{ - RequestRPCResponse response = new RequestRPCResponse(); - response.setHeaders(cr.headers().asHttpHeaders()); - response.setBodyMono(cr.bodyToMono(String.class)); - response.setStatus(cr.statusCode()); - return Mono.just(response); - }); - } - - private Map getResponses(Map stepContext2) { - // TODO Auto-generated method stub - return null; - } - - protected void doOnResponseSuccess(RPCResponse cr, long elapsedMillis) { - HttpHeaders httpHeaders = (HttpHeaders) cr.getHeaders(); - Map headers = new HashMap<>(); - httpHeaders.forEach((key, value) -> { - if (value.size() > 1) { - headers.put(key.toUpperCase(), value); - } else { - headers.put(key.toUpperCase(), httpHeaders.getFirst(key)); - } - }); - headers.put("ELAPSEDTIME", elapsedMillis + "ms"); - - RequestRPCResponse reqCr = (RequestRPCResponse) cr; - synchronized (inputContext.getStepContext()) { - if (reqCr.getStatusCode() != null) { - this.response.put("httpStatus", reqCr.getStatusCode().value()); - } - this.response.put("headers", headers); - this.respContentType = httpHeaders.getFirst(CONTENT_TYPE); - inputContext.getStepContext().addElapsedTime(prefix + request.get("url"), - elapsedMillis); - } - } - protected Mono bodyToMono(ClientResponse cr){ - return cr.bodyToMono(String.class); - } - - protected void doOnBodyError(Throwable ex, long elapsedMillis) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.warn("failed to call {}", request.get("url"), ex); - synchronized (inputContext.getStepContext()) { - inputContext.getStepContext().addElapsedTime( - stepResponse.getStepName() + "-" + "调用接口 failed " + request.get("url"), elapsedMillis); - } - } - - // Parse response body according to content-type header - public Object parseBody(String contentType, String responseBody) { - String[] cts = contentType.split(";"); - Object body = null; - for (int i = 0; i < cts.length; i++) { - String ct = cts[i].toLowerCase(); - switch (ct) { - case CONTENT_TYPE_JSON: - body = JSON.parse(responseBody); - break; - case CONTENT_TYPE_TEXT: - // parse text as json if start with "{" and end with "}" or start with "[" and - // end with "]" - if ((responseBody.startsWith("{") && responseBody.endsWith("}")) - || (responseBody.startsWith("[") && responseBody.endsWith("]"))) { - try { - body = JSON.parse(responseBody); - } catch (Exception e) { - body = responseBody; - } - } else { - body = responseBody; - } - break; - case CONTENT_TYPE_XML: - case CONTENT_TYPE_TEXT_XML: - Builder builder = new XmlToJson.Builder(responseBody); - if (this.xmlArrPaths != null && this.xmlArrPaths.length > 0) { - for (int j = 0; j < this.xmlArrPaths.length; j++) { - String p = this.xmlArrPaths[j]; - builder = builder.forceList(p); - } - } - body = builder.build().toJson().toMap(); - break; - case CONTENT_TYPE_HTML: - body = responseBody; - break; - case CONTENT_TYPE_JS: - body = responseBody; - break; - } - if (body != null) { - break; - } - } - if (body == null) { - body = responseBody; - } - return body; - } - - protected void doOnBodySuccess(Object resp, long elapsedMillis) { - if(inputContext.getStepContext().isDebug()) { - // LogService.setBizId(inputContext.getStepContext().getTraceId()); - ThreadContext.put(Consts.TRACE_ID, inputContext.getStepContext().getTraceId()); - LOGGER.info("{} 耗时:{}ms URL={}, reqHeader={} req={} resp={}", prefix, elapsedMillis, request.get("url"), - JSON.toJSONString(this.request.get("headers")), - JSON.toJSONString(this.request.get("body")), resp); - } - } - - @SuppressWarnings("unused") - private void cleanup(ClientResponse clientResponse) { - if (clientResponse != null) { - clientResponse.bodyToMono(Void.class).subscribe(); - } - } - - @SuppressWarnings("rawtypes") - public static Class inputConfigClass (){ - return RequestInputConfig.class; - } - -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestInputConfig.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestInputConfig.java deleted file mode 100644 index e51d918..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestInputConfig.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.request; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Map; - -import org.apache.commons.lang3.StringUtils; -import org.springframework.util.MultiValueMap; -import org.springframework.web.util.UriComponentsBuilder; - -import com.fizzgate.fizz.input.InputConfig; - - - -/** - * - * @author linwaiwai - * @author Francis Dong - * - */ -public class RequestInputConfig extends InputConfig { - private URL url ; - private String method ; - private int timeout; - private String protocol; - /** - * Service Type, 1 service discovery, 2 HTTP service - */ - private Integer serviceType; - private String serviceName; - private String path; - private long numRetries; - /** - * retry interval in millisecond - */ - private long retryInterval; - - private String registryName; - - public RequestInputConfig(Map configBody) { - super(configBody); - - if (configBody.get("serviceType") != null && StringUtils.isNotBlank((String) configBody.get("protocol")) - && StringUtils.isNotBlank((String) configBody.get("serviceName")) - && StringUtils.isNotBlank((String) configBody.get("path"))) { - serviceType = Integer.valueOf(configBody.get("serviceType").toString()); - protocol = ((String) configBody.get("protocol")).toLowerCase(); - serviceName = (String) configBody.get("serviceName"); - registryName = (String)configBody.get("registryName"); - path = (String) configBody.get("path"); - } else { - String url = (String) configBody.get("url"); - if (StringUtils.isBlank(url)) { - throw new RuntimeException("Request URL can not be blank"); - } - setUrl(url); - } - - if (configBody.get("method") != null) { - setMethod(((String)configBody.get("method")).toUpperCase()); - } else { - setMethod("GET"); - } - if (configBody.get("timeout") != null && StringUtils.isNotBlank(configBody.get("timeout").toString())) { - try { - timeout = Integer.valueOf(configBody.get("timeout").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid timeout: " + configBody.get("timeout").toString() + " " + e.getMessage(), e); - } - } - if (configBody.get("numRetries") != null && StringUtils.isNotBlank(configBody.get("numRetries").toString())) { - try { - numRetries = Long.valueOf(configBody.get("numRetries").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid numRetries: " + configBody.get("numRetries").toString() + " " + e.getMessage(), e); - } - } - if (configBody.get("retryInterval") != null && StringUtils.isNotBlank(configBody.get("retryInterval").toString())) { - try { - retryInterval = Long.valueOf(configBody.get("retryInterval").toString()); - } catch (Exception e) { - throw new RuntimeException("invalid retryInterval: " + configBody.get("retryInterval").toString() + " " + e.getMessage(), e); - } - } - if (configBody.get("fallback") != null) { - Map fallback = (Map)configBody.get("fallback"); - setFallback(fallback); - } - if (configBody.get("condition") != null) { - setCondition((Map)configBody.get("condition")); - } - } - - public boolean isNewVersion() { - if (serviceType != null && StringUtils.isNotBlank(protocol) && StringUtils.isNotBlank(serviceName) - && StringUtils.isNotBlank(path)) { - return true; - } - return false; - } - - public String getQueryStr(){ - return url.getQuery(); - } - - public MultiValueMap getQueryParams(){ - if (isNewVersion()) { - return null; - } - MultiValueMap parameters = - UriComponentsBuilder.fromUriString(url.toString()).build().getQueryParams(); - return parameters; - } - - - public String getBaseUrl() { - return url.getProtocol()+ "://"+ url.getHost() + (url.getPort() == -1 ? "" : ":" + url.getPort()); - } - - public String getPath() { - if (isNewVersion()) { - return this.path; - } - return url.getPath(); - } - - public void setUrl(String string) { - try { - url = new URL(string); - } catch (MalformedURLException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - } - - public RequestInputConfig() { - super(null); - } - - public String getMethod() { - return method; - } - - public void setMethod(String method) { - this.method = method; - } - - public int getTimeout() { - return timeout; - } - - public void setTimeout(int timeout) { - this.timeout = timeout; - } - - public String getProtocol() { - return protocol; - } - - public void setProtocol(String protocol) { - this.protocol = protocol; - } - - public Integer getServiceType() { - return serviceType; - } - - public void setServiceType(Integer serviceType) { - this.serviceType = serviceType; - } - - public String getServiceName() { - return serviceName; - } - - public void setServiceName(String serviceName) { - this.serviceName = serviceName; - } - - public void setPath(String path) { - this.path = path; - } - - public long getNumRetries() { - return numRetries; - } - - public void setNumRetries(long numRetries) { - this.numRetries = numRetries; - } - - public long getRetryInterval() { - return retryInterval; - } - - public void setRetryInterval(long retryInterval) { - this.retryInterval = retryInterval; - } - - public String getRegistryName() { - return registryName; - } - - public void setRegistryName(String registryName) { - this.registryName = registryName; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestRPCResponse.java b/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestRPCResponse.java deleted file mode 100644 index 8518f2c..0000000 --- a/fizz-core/src/main/java/com/fizzgate/fizz/input/extension/request/RequestRPCResponse.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input.extension.request; - -import org.springframework.http.HttpStatus; - -import com.fizzgate.fizz.input.RPCResponse; - -/** - * - * @author linwaiwai - * - */ -public class RequestRPCResponse extends RPCResponse { - private HttpStatus statusCode; - public void setStatus(HttpStatus statusCode) { - this.statusCode = statusCode; - } - - public HttpStatus getStatusCode() { - return statusCode; - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/global_resource/GlobalResourceService.java b/fizz-core/src/main/java/com/fizzgate/global_resource/GlobalResourceService.java index c9751c6..aae885e 100644 --- a/fizz-core/src/main/java/com/fizzgate/global_resource/GlobalResourceService.java +++ b/fizz-core/src/main/java/com/fizzgate/global_resource/GlobalResourceService.java @@ -24,7 +24,6 @@ import org.springframework.data.redis.core.ReactiveStringRedisTemplate; import org.springframework.stereotype.Service; import com.fizzgate.config.AggregateRedisConfig; -import com.fizzgate.fizz.input.PathMapping; import com.fizzgate.util.JacksonUtils; import com.fizzgate.util.Result; @@ -69,10 +68,18 @@ public class GlobalResourceService { } private void updateResNode() { - resNode = PathMapping.toONode(objectMap); + resNode = this.toONode(objectMap); log.info("global resource node is updated, new keys: {}", objectMap.keySet()); } + private ONode toONode(Object obj) { + ONode o; + synchronized (obj) { + o = ONode.loadObj(obj); + } + return o; + } + private Result initGlobalResource() { Result result = Result.succ(); Flux> resources = rt.opsForHash().entries("fizz_global_resource"); diff --git a/fizz-core/src/main/java/com/fizzgate/listener/AggregateChannelListener.java b/fizz-core/src/main/java/com/fizzgate/listener/AggregateChannelListener.java deleted file mode 100644 index 59386fd..0000000 --- a/fizz-core/src/main/java/com/fizzgate/listener/AggregateChannelListener.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2020 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.listener; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.TypeReference; -import com.fizzgate.fizz.ConfigLoader; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.data.redis.connection.ReactiveSubscription; -import org.springframework.data.redis.listener.ChannelTopic; -import org.springframework.data.redis.listener.ReactiveRedisMessageListenerContainer; -import org.springframework.stereotype.Component; -import org.springframework.util.StringUtils; -import reactor.core.Disposable; -import reactor.core.publisher.Flux; -import reactor.core.scheduler.Schedulers; - -import javax.annotation.PostConstruct; -import javax.annotation.PreDestroy; - -import static com.fizzgate.config.AggregateRedisConfig.AGGREGATE_REACTIVE_REDIS_MESSAGE_LISTENER_CONTAINER; - -import java.net.InetAddress; -import java.util.List; - -/** - * 聚合Channel监听器 - * @author zhongjie - */ -@Component -public class AggregateChannelListener { - public AggregateChannelListener(@Qualifier(AGGREGATE_REACTIVE_REDIS_MESSAGE_LISTENER_CONTAINER) - ReactiveRedisMessageListenerContainer reactiveRedisMessageListenerContainer, - ConfigLoader configLoader) { - this.reactiveRedisMessageListenerContainer = reactiveRedisMessageListenerContainer; - this.configLoader = configLoader; - } - - private static final Logger LOGGER = LoggerFactory.getLogger(AggregateChannelListener.class); - /** - * 聚合配置Channel名称,fizz-manager会往该Channel发送聚合变更信息 - */ - private static final String AGGREGATE_CHANNEL = "fizz_aggregate_channel"; - - private ReactiveRedisMessageListenerContainer reactiveRedisMessageListenerContainer; - private ConfigLoader configLoader; - private Disposable disposable; - - @PostConstruct - public void init() { - Flux> aggregateMessageFlux = - reactiveRedisMessageListenerContainer.receive(ChannelTopic.of(AGGREGATE_CHANNEL)); - disposable = aggregateMessageFlux.parallel().runOn(Schedulers.parallel()).subscribe(message -> { - String messageBody = message.getMessage(); - LOGGER.info("获取到[{}]消息[{}]", AGGREGATE_CHANNEL, messageBody); - try { - this.handleAggregateMessage(messageBody); - } catch (Exception e) { - LOGGER.warn(String.format("处理聚合推送数据异常[%s]", message), e); - } - }); - } - - @PreDestroy - public void destroy() { - if (disposable != null && !disposable.isDisposed()) { - disposable.dispose(); - } - } - - private static final String TYPE_PUBLISH = "publish "; - private static final String TYPE_ROLLBACK = "rollback "; - private static final String TYPE_TEST = "test "; - private static final String TYPE_DELETE = "delete "; - private static final String TYPE_REFRESH = "refresh "; - private void handleAggregateMessage(String message) throws Exception { - if (!StringUtils.hasText(message)) { - return; - } - - String type; - String data; - if (message.startsWith(TYPE_PUBLISH)) { - type = TYPE_PUBLISH; - data = message.replace(TYPE_PUBLISH, ""); - } else if (message.startsWith(TYPE_ROLLBACK)) { - type = TYPE_ROLLBACK; - data = message.replace(TYPE_ROLLBACK, ""); - } else if (message.startsWith(TYPE_TEST)) { - type = TYPE_TEST; - data = message.replace(TYPE_TEST, ""); - } else if (message.startsWith(TYPE_DELETE)) { - type = TYPE_DELETE; - data = message.replace(TYPE_DELETE, ""); - } else if (message.startsWith(TYPE_REFRESH)) { - type = TYPE_REFRESH; - // 需要刷新集合配置的节点IP列表 - data = message.replace(TYPE_REFRESH, ""); - } else { - LOGGER.warn(String.format("未知的聚合推送数据[%s]", message)); - return; - } - - switch (type) { - case TYPE_PUBLISH: - case TYPE_ROLLBACK: - case TYPE_TEST: - configLoader.addConfig(data); - break; - case TYPE_DELETE: - configLoader.deleteConfig(data); - break; - case TYPE_REFRESH: - this.refreshConfig(data); - break; - default: - break; - } - } - - private static final TypeReference> STRING_LIST_TYPE_REFERENCE = new TypeReference>() {}; - private void refreshConfig(String allowIps) throws Exception { - if (!this.checkIp(LOCAL_IP, allowIps)) { - // 本机IP不在刷新列表中,直接返回 - LOGGER.info("本机IP地址[{}]不在刷新IP列表[{}]中", LOCAL_IP, allowIps); - return; - } - - // 刷新配置 - configLoader.init(); - } - - private boolean checkIp(String clientIp, String allowIps) { - if (!StringUtils.hasText(allowIps)) { - return true; - } - - List allowIpList = JSON.parseObject(allowIps, STRING_LIST_TYPE_REFERENCE); - for (String allowIp : allowIpList) { - boolean allow = "*".equals(allowIp) || allowIp.equals(clientIp) - || allowIp.contains("-") && ipIsValid(allowIp, clientIp); - if (allow) { - return true; - } - } - return false; - } - - private static final String REGX_IP = "((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"; - private static final String REGX_IPB = REGX_IP + "\\-" + REGX_IP; - - private static boolean ipIsValid(String allowIp, String clientIp) { - if (allowIp == null) { - return false; - } - - if (clientIp == null) { - return false; - } - allowIp = allowIp.trim(); - clientIp = clientIp.trim(); - if (!allowIp.matches(REGX_IPB) || !clientIp.matches(REGX_IP)) { - return false; - } - int idx = allowIp.indexOf('-'); - String[] sips = allowIp.substring(0, idx).split("\\."); - String[] sipe = allowIp.substring(idx + 1).split("\\."); - String[] sipt = clientIp.split("\\."); - long ips = 0L, ipe = 0L, ipt = 0L; - for (int i = 0; i < 4; ++i) { - ips = ips << 8 | Integer.parseInt(sips[i]); - ipe = ipe << 8 | Integer.parseInt(sipe[i]); - ipt = ipt << 8 | Integer.parseInt(sipt[i]); - } - if (ips > ipe) { - long t = ips; - ips = ipe; - ipe = t; - } - return ips <= ipt && ipt <= ipe; - } - - private static final String LOCAL_IP = AggregateChannelListener.getLocalIp(); - private static String getLocalIp() { - try { - InetAddress inetAddress = InetAddress.getLocalHost(); - return inetAddress.getHostAddress(); - } catch (Exception e) { - LOGGER.warn("获取本地IP地址异常", e); - return "unknown"; - } - } -} diff --git a/fizz-core/src/main/java/com/fizzgate/proxy/CallbackService.java b/fizz-core/src/main/java/com/fizzgate/proxy/CallbackService.java index dd14621..dbea2bb 100644 --- a/fizz-core/src/main/java/com/fizzgate/proxy/CallbackService.java +++ b/fizz-core/src/main/java/com/fizzgate/proxy/CallbackService.java @@ -17,6 +17,8 @@ package com.fizzgate.proxy; +import com.fizzgate.aggregate.web.loader.BaseAggregateResult; +import com.fizzgate.aggregate.web.service.AggregateService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.io.buffer.DataBuffer; @@ -31,8 +33,6 @@ import org.springframework.web.server.ServerWebExchange; import com.fizzgate.config.SystemConfig; import com.fizzgate.constants.CommonConstants; -import com.fizzgate.fizz.AggregateResult; -import com.fizzgate.fizz.AggregateService; import com.fizzgate.plugin.auth.ApiConfig; import com.fizzgate.plugin.auth.ApiConfigService; import com.fizzgate.plugin.auth.CallbackConfig; @@ -133,7 +133,7 @@ public class CallbackService { } else if (r instanceof ClientResponse) { return genServerResponse(exchange, (ClientResponse) r); } else { - return aggregateService.genAggregateResponse(exchange, (AggregateResult) r); + return aggregateService.genAggregateResponse(exchange, (BaseAggregateResult) r); } } ) @@ -147,7 +147,7 @@ public class CallbackService { }; } - private Function> arError(ServerWebExchange exchange, Receiver r, HttpMethod method, HttpHeaders headers, DataBuffer body) { + private Function> arError(ServerWebExchange exchange, Receiver r, HttpMethod method, HttpHeaders headers, DataBuffer body) { return t -> { log(exchange, r, method, headers, body, t); return Mono.just(new FailAggregateResult(t)); @@ -289,7 +289,7 @@ public class CallbackService { ; } - private Function> arError(CallbackReplayReq req, String service, String path) { + private Function> arError(CallbackReplayReq req, String service, String path) { return t -> { log(req, service, path, t); return Mono.just(new FailAggregateResult(t)); diff --git a/fizz-core/src/main/java/com/fizzgate/proxy/FailAggregateResult.java b/fizz-core/src/main/java/com/fizzgate/proxy/FailAggregateResult.java index d77f0b6..1dbdcff 100644 --- a/fizz-core/src/main/java/com/fizzgate/proxy/FailAggregateResult.java +++ b/fizz-core/src/main/java/com/fizzgate/proxy/FailAggregateResult.java @@ -17,13 +17,14 @@ package com.fizzgate.proxy; -import com.fizzgate.fizz.AggregateResult; + +import com.fizzgate.aggregate.web.loader.BaseAggregateResult; /** * @author hongqiaowei */ -public class FailAggregateResult extends AggregateResult { +public class FailAggregateResult extends BaseAggregateResult { public Throwable throwable; diff --git a/fizz-core/src/main/java/com/fizzgate/proxy/FizzWebClient.java b/fizz-core/src/main/java/com/fizzgate/proxy/FizzWebClient.java index a430b74..5e75b23 100644 --- a/fizz-core/src/main/java/com/fizzgate/proxy/FizzWebClient.java +++ b/fizz-core/src/main/java/com/fizzgate/proxy/FizzWebClient.java @@ -17,6 +17,7 @@ package com.fizzgate.proxy; +import com.fizzgate.aggregate.core.exception.FizzRuntimeException; import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -26,7 +27,6 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.lang.Nullable; import org.springframework.stereotype.Service; -import org.springframework.util.CollectionUtils; import org.springframework.web.reactive.function.BodyInserter; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.ClientResponse; @@ -35,7 +35,6 @@ import org.springframework.web.reactive.function.client.WebClient; import com.fizzgate.config.ProxyWebClientConfig; import com.fizzgate.config.SystemConfig; import com.fizzgate.exception.ExternalService4xxException; -import com.fizzgate.fizz.exception.FizzRuntimeException; import com.fizzgate.service_registry.RegistryCenterService; import com.fizzgate.util.Consts; import com.fizzgate.util.NetworkUtils; diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/InputValidateTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/InputValidateTests.java deleted file mode 100644 index 40d923a..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/InputValidateTests.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.fizzgate.fizz; - -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.Pipeline; -import com.fizzgate.fizz.input.ClientInputConfig; -import com.fizzgate.fizz.input.Input; - -import com.fizzgate.schema.util.I18nUtils; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * aggregate input validate tests - * - * @author zhongjie - */ -class InputValidateTests { - private Map jsonSchemaDef = ONode.load("{\n" + - " \"properties\": {\n" + - " \"library\": {\n" + - " \"type\": \"string\"\n" + - " }\n" + - " },\n" + - " \"required\": [\n" + - " \"library\"\n" + - " ],\n" + - " \"type\": [\n" + - " \"object\",\n" + - " \"null\"\n" + - " ]\n" + - "}").toObject(Map.class); - - @Test - void inputValidateHeaderTipTest() { - Pipeline pipeline = new Pipeline(); - - ClientInputConfig clientInputConfig = new ClientInputConfig(); - clientInputConfig.setHeadersDef(jsonSchemaDef); - Input input = new Input(); - input.setConfig(clientInputConfig); - Map clientInput = new HashMap<>(16); - clientInput.put("headers", new HashMap<>(0)); - String validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.HEADER.tipZh)); - - I18nUtils.setContextLocale(new Locale("en")); - try { - validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.HEADER.tipEn)); - } finally { - I18nUtils.removeContextLocale(); - } - } - - @Test - void inputValidateQueryParamTipTest() { - Pipeline pipeline = new Pipeline(); - - ClientInputConfig clientInputConfig = new ClientInputConfig(); - clientInputConfig.setParamsDef(jsonSchemaDef); - Input input = new Input(); - input.setConfig(clientInputConfig); - Map clientInput = new HashMap<>(16); - clientInput.put("params", new HashMap<>(0)); - String validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.QUERY_PARAM.tipZh)); - - I18nUtils.setContextLocale(new Locale("en")); - try { - validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.QUERY_PARAM.tipEn)); - } finally { - I18nUtils.removeContextLocale(); - } - } - - @Test - void inputValidateBodyTipTest() { - Pipeline pipeline = new Pipeline(); - - ClientInputConfig clientInputConfig = new ClientInputConfig(); - clientInputConfig.setBodyDef(jsonSchemaDef); - Input input = new Input(); - input.setConfig(clientInputConfig); - Map clientInput = new HashMap<>(16); - clientInput.put("body", new HashMap<>(0)); - String validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.BODY.tipZh)); - - I18nUtils.setContextLocale(new Locale("en")); - try { - validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.BODY.tipEn)); - } finally { - I18nUtils.removeContextLocale(); - } - } - - @Test - void inputValidateScriptTipTest() { - Pipeline pipeline = new Pipeline(); - - ClientInputConfig clientInputConfig = new ClientInputConfig(); - Map scriptValidate = new HashMap<>(4); - scriptValidate.put("type", "groovy"); - scriptValidate.put("source", "import java.util.List; import java.util.ArrayList; " + - "List errorList = new ArrayList<>(1); errorList.add(\"same thing error\"); return errorList;"); - clientInputConfig.setScriptValidate(scriptValidate); - Input input = new Input(); - input.setConfig(clientInputConfig); - Map clientInput = new HashMap<>(16); - String validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.SCRIPT.tipZh)); - - I18nUtils.setContextLocale(new Locale("en")); - try { - validateMsg = pipeline.inputValidate(input, clientInput); - assertNotNull(validateMsg); - assertTrue(validateMsg.startsWith(Pipeline.ValidateType.SCRIPT.tipEn)); - } finally { - I18nUtils.removeContextLocale(); - } - } -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/component/CircleTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/component/CircleTests.java deleted file mode 100644 index 2e93bfd..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/component/CircleTests.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.component; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.component.OperatorEnum; -import com.fizzgate.fizz.component.StepContextPosition; -import com.fizzgate.fizz.component.circle.Circle; -import com.fizzgate.fizz.component.circle.CircleItem; -import com.fizzgate.fizz.component.condition.Condition; -import com.fizzgate.fizz.component.condition.ConditionValue; -import com.fizzgate.fizz.field.FixedDataTypeEnum; -import com.fizzgate.fizz.field.RefDataTypeEnum; -import com.fizzgate.fizz.field.ValueTypeEnum; -import com.fizzgate.fizz.input.PathMapping; - -class CircleTests { - @Test - void contextLoads() { - } - - @SuppressWarnings("rawtypes") - @Test - void testNextFixedDataSource() { - ONode ctxNode = ONode.load(new HashMap()); - - // FIXED data source - Circle c = new Circle(null, ValueTypeEnum.FIXED, 3, null, null); - CircleItem circleItem = c.next(ctxNode); - assertEquals(1, (Integer) circleItem.getItem()); - - circleItem = c.next(ctxNode); - assertEquals(2, (Integer) circleItem.getItem()); - - circleItem = c.next(ctxNode); - assertEquals(3, (Integer) circleItem.getItem()); - - circleItem = c.next(ctxNode); - assertEquals(null, circleItem); - - } - - @Test - void testNextRefDataSource() { - ONode ctxNode = ONode.load(new HashMap()); - - List list1 = new ArrayList<>(); - list1.add("1"); - list1.add("2"); - list1.add("3"); - PathMapping.setByPath(ctxNode, "data.list1", list1, true); - - // REF data source - Circle c = new Circle(null, ValueTypeEnum.REF, "data.list1", null, null); - CircleItem circleItem = c.next(ctxNode); - assertEquals("1", (String) circleItem.getItem()); - - circleItem = c.next(ctxNode); - assertEquals("2", (String) circleItem.getItem()); - - circleItem = c.next(ctxNode); - assertEquals("3", (String) circleItem.getItem()); - - circleItem = c.next(ctxNode); - assertEquals(null, circleItem); - - } - - @Test - void testExecCondition() { - ONode ctxNode = ONode.load(new HashMap()); - - List list1 = new ArrayList<>(); - list1.add("0"); - list1.add("1"); - list1.add("2"); - list1.add("3"); - list1.add("4"); - - PathMapping.setByPath(ctxNode, "data.list1", list1, true); - - ConditionValue bValue1 = new ConditionValue(ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "3"); - ConditionValue bValue2 = new ConditionValue(ValueTypeEnum.REF, RefDataTypeEnum.STRING, "item"); - Condition c1 = new Condition(null, bValue1, OperatorEnum.NE, bValue2); - - List execConditions = new ArrayList<>(); - execConditions.add(c1); - - Circle circle = new Circle(null, ValueTypeEnum.REF, "data.list1", execConditions, null); - - for (int i = 0; i < 5; i++) { - CircleItem circleItem = circle.next(ctxNode); - PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true); - PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true); - boolean rs = circle.canExec(circleItem.getIndex(), ctxNode, new StepContext(), - new StepContextPosition("step1", null)); - assertEquals(i, circleItem.getIndex()); - if (i < 3) { - assertEquals(true, rs); - } - if (i == 3) { - assertEquals(false, rs); - break; - } - } - - } - - @Test - void testBreakCondition() { - ONode ctxNode = ONode.load(new HashMap()); - - List list1 = new ArrayList<>(); - list1.add("0"); - list1.add("1"); - list1.add("2"); - list1.add("3"); - list1.add("4"); - - PathMapping.setByPath(ctxNode, "data.list1", list1, true); - - ConditionValue bValue1 = new ConditionValue(ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "3"); - ConditionValue bValue2 = new ConditionValue(ValueTypeEnum.REF, RefDataTypeEnum.STRING, "item"); - Condition c1 = new Condition(null, bValue1, OperatorEnum.EQ, bValue2); - - List breakConditions = new ArrayList<>(); - breakConditions.add(c1); - - Circle circle = new Circle(null, ValueTypeEnum.REF, "data.list1", null, breakConditions); - - for (int i = 0; i < 5; i++) { - CircleItem circleItem = circle.next(ctxNode); - PathMapping.setByPath(ctxNode, "item", circleItem.getItem(), true); - PathMapping.setByPath(ctxNode, "index", circleItem.getIndex(), true); - - boolean rs = circle.breakCircle(circleItem.getIndex(), ctxNode, new StepContext(), - new StepContextPosition("step1", null)); - assertEquals(i, circleItem.getIndex()); - if (i < 3) { - assertEquals(false, rs); - } - if (i == 3) { - assertEquals(true, rs); - break; - } - } - - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/component/ConditionTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/component/ConditionTests.java deleted file mode 100644 index b28df21..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/component/ConditionTests.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.component; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import javax.validation.constraints.AssertTrue; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.component.OperatorEnum; -import com.fizzgate.fizz.component.condition.Condition; -import com.fizzgate.fizz.component.condition.ConditionValue; -import com.fizzgate.fizz.field.FixedDataTypeEnum; -import com.fizzgate.fizz.field.RefDataTypeEnum; -import com.fizzgate.fizz.field.ValueTypeEnum; -import com.fizzgate.fizz.input.PathMapping; - -/** - * - * @author Francis Dong - * - */ -class ConditionTests { - @Test - void contextLoads() { - } - - private static final Boolean TRUE = true; - private static final Boolean FALSE = false; - - @Test - void testExec() { - ONode ctxNode = ONode.load(new HashMap()); - - Map m = new HashMap<>(); - m.put("int", 1); - m.put("long", 2); - m.put("float", 3.1); - m.put("double", 4.21); - m.put("string_abcd", "abcd"); - m.put("string_1", "1"); - m.put("string_8", "8"); - m.put("string_blank", ""); - m.put("bool_true", true); - m.put("bool_false", false); - - List list1 = new ArrayList<>(); - list1.add("0"); - list1.add("1"); - list1.add("2"); - list1.add("3"); - list1.add("4"); - - List list2 = new ArrayList<>(); - list2.add("1"); - list2.add("3"); - list2.add("223"); - - List intList = new ArrayList<>(); - intList.add(0); - intList.add(1); - intList.add(2); - intList.add(3); - intList.add(4); - - List floatList = new ArrayList<>(); - floatList.add(0f); - floatList.add(1f); - floatList.add(2f); - floatList.add(3f); - floatList.add(4f); - - PathMapping.setByPath(ctxNode, "data.m", m, true); - PathMapping.setByPath(ctxNode, "data.list1", list1, true); - PathMapping.setByPath(ctxNode, "data.list2", list2, true); - PathMapping.setByPath(ctxNode, "data.intList", intList, true); - PathMapping.setByPath(ctxNode, "data.floatList", floatList, true); - PathMapping.setByPath(ctxNode, "data.emptyList", new ArrayList<>(), true); - - // boolean - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, TRUE, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.EQ, FALSE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.REF, - RefDataTypeEnum.BOOLEAN, "data.m.bool_true", OperatorEnum.EQ, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.REF, - RefDataTypeEnum.BOOLEAN, "data.m.bool_false", OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.REF, - RefDataTypeEnum.BOOLEAN, "data.m.bool_true", OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.REF, null, - "data.m.a", OperatorEnum.EQ, FALSE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.GT, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.GE, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, TRUE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, TRUE, OperatorEnum.GE, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, TRUE, OperatorEnum.LT, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.BOOLEAN, FALSE, ValueTypeEnum.FIXED, - FixedDataTypeEnum.BOOLEAN, FALSE, OperatorEnum.LE, TRUE }); - - // number - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 1, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 2, OperatorEnum.EQ, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 1.000, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 2.1, OperatorEnum.EQ, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.0, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 1.000, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 2.1, OperatorEnum.EQ, FALSE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 2.1, OperatorEnum.GT, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 0.1, OperatorEnum.GE, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 0.1, OperatorEnum.LT, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 1.1, ValueTypeEnum.FIXED, - FixedDataTypeEnum.NUMBER, 4, OperatorEnum.LT, TRUE }); - - // collection - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "2", OperatorEnum.CONTAINS, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_1", OperatorEnum.CONTAINS, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.CONTAINS, FALSE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "2", OperatorEnum.NOTCONTAIN, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_1", OperatorEnum.NOTCONTAIN, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.NOTCONTAIN, TRUE }); - - // collection contains any - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.ARRAY, "data.list2", OperatorEnum.CONTAINSANY, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.ARRAY, "data.intList", OperatorEnum.CONTAINSANY, FALSE }); - - // Collection - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "2", OperatorEnum.CONTAINS, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.REF, - RefDataTypeEnum.INT, "data.m.int", OperatorEnum.CONTAINS, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED, - RefDataTypeEnum.INT, 2, OperatorEnum.CONTAINS, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED, - RefDataTypeEnum.INT, 9, OperatorEnum.CONTAINS, FALSE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "2", OperatorEnum.NOTCONTAIN, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.REF, - RefDataTypeEnum.INT, "data.m.int", OperatorEnum.NOTCONTAIN, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED, - RefDataTypeEnum.INT, 2, OperatorEnum.NOTCONTAIN, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.intList", ValueTypeEnum.FIXED, - RefDataTypeEnum.INT, 9, OperatorEnum.NOTCONTAIN, TRUE }); - - // Collection - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList", - ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "2", OperatorEnum.CONTAINS, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList", ValueTypeEnum.REF, - RefDataTypeEnum.INT, "data.m.int", OperatorEnum.CONTAINS, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList", - ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 2, OperatorEnum.CONTAINS, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.floatList", - ValueTypeEnum.FIXED, FixedDataTypeEnum.NUMBER, 2.0, OperatorEnum.CONTAINS, TRUE }); - - // String - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, null, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, null, OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "1", OperatorEnum.EQ, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "1", OperatorEnum.EQ, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.EQ, FALSE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, null, OperatorEnum.NE, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, null, OperatorEnum.NE, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, null, ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "1", OperatorEnum.NE, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "1", OperatorEnum.NE, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.NE, TRUE }); - - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "1", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.GT, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.GT, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.GE, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.LT, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.FIXED, FixedDataTypeEnum.STRING, "11", ValueTypeEnum.FIXED, - FixedDataTypeEnum.STRING, "21", OperatorEnum.LE, TRUE }); - - // Is null - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNULL, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", - ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNULL, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null, - OperatorEnum.ISNULL, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null, - OperatorEnum.ISNULL, FALSE }); - - // Is not null - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNOTNULL, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", - ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNOTNULL, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null, - OperatorEnum.ISNOTNULL, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null, - OperatorEnum.ISNOTNULL, TRUE }); - - // Is Blank - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISBLANK, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", - ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISBLANK, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null, - OperatorEnum.ISBLANK, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null, - OperatorEnum.ISBLANK, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_blank", null, null, - null, OperatorEnum.ISBLANK, TRUE }); - - // Is not Blank - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNOTBLANK, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", - ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNOTBLANK, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null, - OperatorEnum.ISNOTBLANK, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_8", null, null, null, - OperatorEnum.ISNOTBLANK, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.STRING, "data.m.string_blank", null, null, - null, OperatorEnum.ISNOTBLANK, FALSE }); - - // Is empty - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISEMPTY, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISEMPTY, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null, - OperatorEnum.ISEMPTY, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", null, null, null, - OperatorEnum.ISEMPTY, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.emptyList", null, null, null, - OperatorEnum.ISEMPTY, TRUE }); - - // Is not empty - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNOTEMPTY, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", ValueTypeEnum.REF, - RefDataTypeEnum.STRING, "data.m.string_8", OperatorEnum.ISNOTEMPTY, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list11111", null, null, null, - OperatorEnum.ISNOTEMPTY, FALSE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.list1", null, null, null, - OperatorEnum.ISNOTEMPTY, TRUE }); - this.run(ctxNode, new Object[] { ValueTypeEnum.REF, RefDataTypeEnum.ARRAY, "data.emptyList", null, null, null, - OperatorEnum.ISNOTEMPTY, FALSE }); - - } - - private void run(ONode ctxNode, Object[] item) { - ConditionValue bValue1 = null; - if (item[1] instanceof FixedDataTypeEnum) { - bValue1 = new ConditionValue((ValueTypeEnum) item[0], (FixedDataTypeEnum) item[1], item[2]); - } else { - bValue1 = new ConditionValue((ValueTypeEnum) item[0], (RefDataTypeEnum) item[1], item[2]); - } - ConditionValue bValue2 = null; - if (item[3] != null) { - if (item[4] instanceof FixedDataTypeEnum) { - bValue2 = new ConditionValue((ValueTypeEnum) item[3], (FixedDataTypeEnum) item[4], item[5]); - } else { - bValue2 = new ConditionValue((ValueTypeEnum) item[3], (RefDataTypeEnum) item[4], item[5]); - } - } - Condition c = new Condition(null, bValue1, (OperatorEnum) item[6], bValue2); - boolean rs = c.exec(ctxNode); - boolean expected = (boolean) item[7]; - assertEquals(expected, rs); - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/CodecFuncTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/CodecFuncTests.java deleted file mode 100644 index 0c1609b..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/CodecFuncTests.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.function.FuncExecutor; -import com.fizzgate.fizz.input.PathMapping; -import com.fizzgate.util.DigestUtils; - -/** - * - * @author Francis Dong - * - */ -class CodecFuncTests { - @Test - void contextLoads() { - } - - - @Test - void testMd5() { - String funcExpression = "fn.codec.md5(\"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("900150983cd24fb0d6963f7d28e17f72", result.toString()); - } - - @Test - void testMd5_2() { - String funcExpression = "fn.codec.md5(fn.date.add(fn.date.add(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\", 1, fn.math.addExact(999,1)), \"yyyy-MM-dd HH:mm:ss\", fn.math.addExact(0,1), 1000))"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(DigestUtils.md5Hex("2021-07-09 22:44:57"), result.toString()); - } - - @Test - void testSha1() { - String funcExpression = "fn.codec.sha1(\"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("a9993e364706816aba3e25717850c26c9cd0d89d", result.toString()); - } - - @Test - void testSha256() { - String funcExpression = "fn.codec.sha256(\"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", result.toString()); - } - - @Test - void testSha384() { - String funcExpression = "fn.codec.sha384(\"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7", result.toString()); - } - - @Test - void testSha512() { - String funcExpression = "fn.codec.sha512(\"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f", result.toString()); - } - - @Test - void testBase64Encode() { - String funcExpression = "fn.codec.base64Encode(\"Base64编码介绍\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("QmFzZTY057yW56CB5LuL57uN", result.toString()); - } - - // @Test - void testBase64Decode() { - String funcExpression = "fn.codec.base64Decode(\"QmFzZTY057yW56CB5LuL57uN\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("Base64编码介绍", result.toString()); - } - - @Test - void testAesEncrypt() { - String funcExpression = "fn.codec.aesEncrypt(\"abc\", \"1234567812345678\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("ucSL5R/jQigQ1dxzsWi2kg==", result.toString()); - } - - @Test - void testAesDecrypt() { - String funcExpression = "fn.codec.aesDecrypt(\"ucSL5R/jQigQ1dxzsWi2kg==\", \"1234567812345678\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("abc", result.toString()); - } - - @Test - void testDesEncrypt() { - String funcExpression = "fn.codec.desEncrypt(\"abc\", \"12345678123456781234567812345678\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("9YR6ZPdZufM=", result.toString()); - } - - @Test - void testDesDecrypt() { - String funcExpression = "fn.codec.desDecrypt(\"9YR6ZPdZufM=\", \"12345678123456781234567812345678\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("abc", result.toString()); - } - - @Test - void testHmacSha256() { - String funcExpression = "fn.codec.hmacSha256(\"12345678123456781234567812345678\", \"635e8562b968bc05bb80cacf124ebd53285280ee6845df0000faa33acafc38f0\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("c61be0237ec186df1c5f51425e607093b260a76e5de43a62cb3e821103303990", result.toString()); - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/CommonFuncTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/CommonFuncTests.java deleted file mode 100644 index a195e6a..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/CommonFuncTests.java +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.function.FuncExecutor; -import com.fizzgate.fizz.input.PathMapping; - -/** - * - * @author Francis Dong - * - */ -class CommonFuncTests { - - @Test - void contextLoads() { - } - - private Map createRecord(String key, Object value) { - Map m = new HashMap<>(); - m.put(key, value); - return m; - } - - private ONode getCtxNode() { - ONode ctxNode = ONode.load(new HashMap()); - - Map m = new HashMap<>(); - m.put("a", "1"); - m.put("b", "1"); - m.put("d", ""); - m.put("true", true); - m.put("false", false); - m.put("blank", ""); - m.put("null", null); - m.put("stringtrue", "true"); - m.put("stringfalse", "false"); - m.put("string1", "1"); - m.put("string0", "0"); - m.put("stringabc", "abc"); - m.put("int1", "1"); - m.put("int0", "0"); - m.put("int2", "2"); - - List list = new ArrayList<>(); - list.add(createRecord("a", "a1")); - list.add(createRecord("a", "a2")); - list.add(createRecord("a", "a3")); - - List list2 = new ArrayList<>(); - - PathMapping.setByPath(ctxNode, "data.m", m, true); - PathMapping.setByPath(ctxNode, "data.m2", new HashMap<>(), true); - PathMapping.setByPath(ctxNode, "data.list", list, true); - PathMapping.setByPath(ctxNode, "data.list2", list2, true); - return ctxNode; - } - - @Test - void testIif() { - String funcExpression = "fn.common.iif(true, \"abc\", \"xyz\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("abc", result.toString()); - } - - - @Test - void testIif2() { - String funcExpression = "fn.common.iif(false, \"abc\", \"xyz\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("xyz", result.toString()); - } - - @Test - void testIif3() { - String funcExpression = "fn.common.iif(false, \"abc\", 123)"; - Long result = (Long)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(123, result.intValue()); - } - - @Test - void testIif4() { - String funcExpression = "fn.common.iif(false, \"abc\", 123.4)"; - Double result = (Double)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(123.4, result); - } - - @Test - void testIif5() { - String funcExpression = "fn.common.iif(false, \"abc\", true)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals() { - String funcExpression = "fn.common.equals(\"abc\", true)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(false, result); - } - - @Test - void testEquals2() { - String funcExpression = "fn.common.equals(\"abc\", \"abc\")"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals3() { - String funcExpression = "fn.common.equals(123, 123)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals4() { - String funcExpression = "fn.common.equals(123, 123.0)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(false, result); - } - - @Test - void testEquals5() { - String funcExpression = "fn.common.equals(true, true)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals6() { - String funcExpression = "fn.common.equals(123.2, 123.2)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals7() { - String funcExpression = "fn.common.equals(null, 123.2)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(false, result); - } - - @Test - void testEquals8() { - String funcExpression = "fn.common.equals(null, null)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals9() { - String funcExpression = "fn.common.equals(123, null)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(false, result); - } - - @Test - void testIsNull() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.isNull({data.m.c})"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - } - - @Test - void testIsNotNull() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.isNotNull({data.m.a})"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - } - - @Test - void testIsBlank() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.isBlank({data.m.c})"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - } - - @Test - void testIsNotBlank() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.isNotBlank({data.m.a})"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - } - - @Test - void testIsEmpty() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.isEmpty({data.list2})"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.isEmpty({data.m2})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.isEmpty({data.m.x})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.isEmpty({data.m.d})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - } - - @Test - void testIsNotEmpty() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.isNotEmpty({data.list})"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.isNotEmpty({data.m})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.isNotEmpty({data.m.a})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.isNotEmpty({data.m.y})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - } - - @Test - void testAnd() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.and(true, true)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and(true, true, true)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and(true)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and({data.m.true}, {data.m.true}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and({data.m.true}, {data.m.true}, {data.m.true}, {data.m.notexist})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.true}, {data.m.true}, {data.m.true}, {data.m.null})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.true}, {data.m.true}, {data.m.true}, {data.m.blank})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.true}, {data.m.false}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.false}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.false})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.true}, {data.m.notexist})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.notexist})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and()"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.blank})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.null})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.int1})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and({data.m.int0})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.string1})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and({data.m.string0})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.stringabc})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.stringtrue})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.and({data.m.stringfalse})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.and({data.m.int2})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - } - - @Test - void testOr() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.or(true, true)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or(true, true, true)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or(false, true)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or(true)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or(false)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or(true, false, true)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.true}, {data.m.true}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.true}, {data.m.true}, {data.m.false})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.false}, {data.m.true}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.false}, {data.m.notexist}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.false}, {data.m.null}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.false}, {data.m.blank}, {data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.false}, {data.m.false}, {data.m.false})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.false}, {data.m.false})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.false})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.null})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.blank})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.notexist})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or()"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.true})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.int1})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.int0})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.string1})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.string0})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.stringabc})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.stringtrue})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.or({data.m.stringfalse})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.or({data.m.int2})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - } - - @Test - void testNot() { - ONode ctx = getCtxNode(); - String funcExpression = "fn.common.not(true)"; - Boolean result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.not(false)"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.blank})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.null})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.notexist})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.string1})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.not({data.m.string0})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.stringabc})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.stringtrue})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.not({data.m.stringfalse})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.int1})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(false, result); - - funcExpression = "fn.common.not({data.m.int0})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - - funcExpression = "fn.common.not({data.m.int2})"; - result = (Boolean)FuncExecutor.getInstance().exec(ctx, funcExpression); - assertEquals(true, result); - } -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/DateFuncTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/DateFuncTests.java deleted file mode 100644 index 075b75b..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/DateFuncTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -import com.fizzgate.fizz.function.FuncExecutor; - -/** - * - * @author Francis Dong - * - */ -class DateFuncTests { - @Test - void contextLoads() { - } - - @Test - void testTimestamp() { - String funcExpression = "fn.date.timestamp()"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - System.out.println(result); - } - - @Test - void testNow() { - String funcExpression = "fn.date.now(null)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - System.out.println(result); - } - -// @Test -// void testNow2() { -// String funcExpression = "fn.date.now()"; -// Object result = FuncExecutor.getInstance().exec(null, funcExpression); -// System.out.println(result); -// } - - @Test - void testGetTime() { - String funcExpression = "fn.date.getTime(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\")"; - Long result = (Long)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(1625841895000l, result.longValue()); - } - - @Test - void testAdd() { - String funcExpression = "fn.date.add(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\", 1, 1000)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:56", result.toString()); - } - - @Test - void testEmbeddedAdd() { - String funcExpression = "fn.date.add(fn.date.add(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\", 1, 1000), \"yyyy-MM-dd HH:mm:ss\", 1, 1000)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:57", result.toString()); - } - - - @Test - void testFormatTs() { - String funcExpression = "fn.date.formatTs(1628825352227, \"yyyy-MM-dd HH:mm:ss\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-08-13 11:29:12", result.toString()); - } - - @Test - void testChangePattern() { - String funcExpression = "fn.date.changePattern(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\", \"MM-dd HH:mm\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("07-09 22:44", result.toString()); - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/FuncExecutorTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/FuncExecutorTests.java deleted file mode 100644 index 2972aed..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/FuncExecutorTests.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -import com.fizzgate.fizz.function.CodecFunc; -import com.fizzgate.fizz.function.FuncExecutor; - -/** - * - * @author Francis Dong - * - */ -class FuncExecutorTests { - - @Test - void contextLoads() { - } - - - @Test - void testNest() { - String funcExpression = "fn.codec.md5(fn.date.add( fn.date.add(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\", 1, fn.math.addExact(999,1 ) ), \"yyyy-MM-dd HH:mm:ss\", fn.math.addExact(0,1), 1000 ))"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(CodecFunc.getInstance().md5("2021-07-09 22:44:57"), result); - } - - @Test - void testNest2() { - String funcExpression = "fn.string.toUpperCase(fn.codec.sha256(fn.string.concat(\"a\",\"b\",fn.string.toString(fn.date.timestamp()))))"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - System.out.println(result); - } - - @Test - void testNest3() { - String funcExpression = "fn.string.toUpperCase(fn.string.concat(\"a\",\"b\", fn.string.concat())))"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("AB", result); - } - - @Test - void testNest4() { - String funcExpression = "fn.string.toUpperCase(fn.codec.sha256(fn.string.concat(\"a\",fn.string.concat(),\"b\")))"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - System.out.println(result); - } - - @Test - void testNest5() { - String funcExpression = "fn.string.toUpperCase(fn.codec.sha256(fn.string.concat(\"a\",fn.string.toString(fn.date.timestamp()),fn.string.concat(fn.string.concat(fn.string.concat(fn.string.concat())), \"c\"),\"b\")))"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - System.out.println(result); - } - - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/ListFuncTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/ListFuncTests.java deleted file mode 100644 index 81957fa..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/ListFuncTests.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.alibaba.fastjson.JSON; -import com.fizzgate.fizz.function.FuncExecutor; -import com.fizzgate.fizz.input.PathMapping; - -/** - * - * @author Francis Dong - * - */ -@SuppressWarnings({ "rawtypes", "unchecked" }) -class ListFuncTests { - @Test - void contextLoads() { - } - - private Map createRecord(String key, Object value) { - Map m = new HashMap<>(); - m.put(key, value); - return m; - } - - private Map createRecord2(int index) { - Map m = new HashMap<>(); - m.put("a", "a" + index); - m.put("b", "b" + index); - m.put("c", "c" + index); - m.put("d", "d" + index); - m.put("e", "e" + index); - return m; - } - - @Test - void testExpand() { - List> data = new ArrayList<>(); - - List subList1 = new ArrayList<>(); - subList1.add(createRecord("a", "a1")); - subList1.add(createRecord("a", "a2")); - subList1.add(createRecord("a", "a3")); - - List subList2 = new ArrayList<>(); - subList2.add(createRecord("a", "a4")); - subList2.add(createRecord("a", "a5")); - subList2.add(createRecord("a", "a6")); - - data.add(subList1); - data.add(subList2); - - ONode ctxNode = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode, "test.data", data, true); - - String funcExpression = "fn.list.expand({test.data})"; - List result = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression); - assertEquals(6, result.size()); - assertEquals("a2", ((Map) result.get(1)).get("a").toString()); - assertEquals("a4", ((Map) result.get(3)).get("a").toString()); - } - - @Test - void testMerge() { - List subList1 = new ArrayList<>(); - subList1.add(createRecord("a", "a1")); - subList1.add(createRecord("a", "a2")); - subList1.add(createRecord("a", "a3")); - - List subList2 = new ArrayList<>(); - subList2.add(createRecord("a", "a4")); - subList2.add(createRecord("a", "a5")); - subList2.add(createRecord("a", "a6")); - - ONode ctxNode = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode, "test.data1", subList1, true); - PathMapping.setByPath(ctxNode, "test.data2", subList2, true); - - String funcExpression = "fn.list.merge({test.data1}, {test.data2})"; - List result = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression); - assertEquals(6, result.size()); - assertEquals("a2", ((Map) result.get(1)).get("a").toString()); - assertEquals("a4", ((Map) result.get(3)).get("a").toString()); - } - - @Test - void testExtract() { - List subList1 = new ArrayList<>(); - subList1.add(createRecord2(1)); - subList1.add(createRecord2(2)); - subList1.add(createRecord2(3)); - subList1.add(createRecord2(4)); - subList1.add(createRecord2(5)); - - ONode ctxNode = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode, "test.data", subList1, true); - - String funcExpression = "fn.list.extract({test.data}, \"c\",\"b\", \"e\")"; - List result = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression); - assertEquals(5, result.size()); - assertEquals("c2", ((Map) result.get(1)).get("c").toString()); - assertEquals("e4", ((Map) result.get(3)).get("e").toString()); - assertEquals(null, ((Map) result.get(3)).get("a")); - assertEquals(null, ((Map) result.get(3)).get("d")); -// System.out.println(result); - } - - private Map createRecord3(int index, boolean isDest) { - Map m = new HashMap<>(); - m.put("a", "a" + index); - String s = isDest ? "" + index : index + "-abc"; - m.put("b", "b" + s); - m.put("c", "c" + s); - if (!isDest) { - m.put("d", "d" + s); - m.put("e", "e" + s); - } - return m; - } - - @Test - void testJoin() { - List list1 = new ArrayList<>(); - list1.add(createRecord3(1, true)); - list1.add(createRecord3(2, true)); - list1.add(createRecord3(3, true)); - list1.add(createRecord3(4, true)); - list1.add(createRecord3(5, true)); - - List list2 = new ArrayList<>(); - list2.add(createRecord3(1, false)); - list2.add(createRecord3(2, false)); - list2.add(createRecord3(3, false)); - list2.add(createRecord3(4, false)); - - ONode ctxNode = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode, "test.list1", list1, true); - PathMapping.setByPath(ctxNode, "test.list2", list2, true); - - String funcExpression = "fn.list.join({test.list1}, {test.list2},\"a\",\"c\",\"d\")"; - List result = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression); - assertEquals(5, result.size()); - assertEquals("a2", ((Map) result.get(1)).get("a").toString()); - assertEquals("d4-abc", ((Map) result.get(3)).get("d").toString()); - // System.out.println(JSON.toJSONString(result)); - - String json1 = "[\n" - + " {\n" - + " \"itemType\": \"3\",\n" - + " \"currCd\": \"156\",\n" - + " \"batchDate\": \"20190331\",\n" - + " \"itemCd\": \"ORGAP0008\",\n" - + " \"itemVal\": 0.7189,\n" - + " \"itemNm\": \"balance rate\",\n" - + " \"valueStr\": \"0.7189\",\n" - + " \"orgCd1\": \"230009999\"\n" - + " },\n" - + " {\n" - + " \"itemType\": \"3\",\n" - + " \"currCd\": \"156\",\n" - + " \"batchDate\": \"20190331\",\n" - + " \"itemCd\": \"ORGAP0008\",\n" - + " \"itemVal\": 0.7040,\n" - + " \"itemNm\": \"balance rate\",\n" - + " \"valueStr\": \"0.7040\",\n" - + " \"orgCd1\": \"230009999\"\n" - + " },\n" - + " {\n" - + " \"itemType\": \"3\",\n" - + " \"currCd\": \"156\",\n" - + " \"batchDate\": \"20190331\",\n" - + " \"itemCd\": \"ORGAP0008\",\n" - + " \"itemVal\": 0.7040,\n" - + " \"itemNm\": \"balance rate\",\n" - + " \"valueStr\": \"0.7040\",\n" - + " \"orgCd1\": \"231009999\"\n" - + " }\n" - + " ]"; - - String json2 = "[\n" - + " {\n" - + " \"orgName\": \"Name1\",\n" - + " \"orgCd\": \"230009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name2\",\n" - + " \"orgCd\": \"231009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name3\",\n" - + " \"orgCd\": \"232009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name3\",\n" - + " \"orgCd\": \"233009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name4\",\n" - + " \"orgCd\": \"234009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name5\",\n" - + " \"orgCd\": \"235009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name6\",\n" - + " \"orgCd\": \"236009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name7\",\n" - + " \"orgCd\": \"237009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name8\",\n" - + " \"orgCd\": \"238009999\"\n" - + " },\n" - + " {\n" - + " \"orgName\": \"Name9\",\n" - + " \"orgCd\": \"239009999\"\n" - + " }\n" - + " ]"; - - - ONode ctxNode2 = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode2, "test.list1", JSON.parseArray(json1, Map.class), true); - PathMapping.setByPath(ctxNode2, "test.list2", JSON.parseArray(json2, Map.class), true); - String funcExpression2 = "fn.list.join({test.list1},{test.list2},\"orgCd1:orgCd\")"; - List result2 = (List) FuncExecutor.getInstance().exec(ctxNode2, funcExpression2); - System.out.println(JSON.toJSONString(result2)); - assertEquals("Name1", ((Map) result2.get(0)).get("orgName").toString()); - } - - @Test - void testRename() { - List subList1 = new ArrayList<>(); - subList1.add(createRecord2(1)); - subList1.add(createRecord2(2)); - subList1.add(createRecord2(3)); - subList1.add(createRecord2(4)); - subList1.add(createRecord2(5)); - - List subList2 = new ArrayList<>(); - subList2.add(createRecord2(1)); - Map m2 = createRecord2(2); - m2.put("b", "b22222"); - subList2.add(m2); - subList2.add(createRecord2(3)); - Map m4 = createRecord2(4); - m4.put("e", "e44444"); - subList2.add(m4); - subList2.add(createRecord2(5)); - - ONode ctxNode = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode, "test.data", subList1, true); - PathMapping.setByPath(ctxNode, "test.data2", subList2, true); - - String funcExpression = "fn.list.rename({test.data}, \"b:birthday\", \"e:email\")"; - List result = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression); - System.out.println(JSON.toJSONString(result)); - assertEquals(5, result.size()); - assertEquals("b2", ((Map) result.get(1)).get("birthday").toString()); - assertEquals("e4", ((Map) result.get(3)).get("email").toString()); - assertEquals(null, ((Map) result.get(3)).get("b")); - assertEquals(null, ((Map) result.get(3)).get("e")); - - - String funcExpression2 = "fn.list.join({test.data}, fn.list.rename({test.data2}, \"b:birthday\", \"e:email\"), \"a\", \"birthday\", \"email\")"; - List result2 = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression2); - System.out.println(JSON.toJSONString(result2)); - assertEquals(5, result2.size()); - assertEquals("b2", ((Map) result2.get(1)).get("b").toString()); - assertEquals("e4", ((Map) result2.get(3)).get("e").toString()); - assertEquals("b22222", ((Map) result2.get(1)).get("birthday").toString()); - assertEquals("e44444", ((Map) result2.get(3)).get("email").toString()); - } - - @Test - void testRemoveFields() { - List subList1 = new ArrayList<>(); - subList1.add(createRecord2(1)); - subList1.add(createRecord2(2)); - subList1.add(createRecord2(3)); - subList1.add(createRecord2(4)); - subList1.add(createRecord2(5)); - - ONode ctxNode = ONode.load(new HashMap()); - PathMapping.setByPath(ctxNode, "test.data", subList1, true); - - String funcExpression = "fn.list.removeFields({test.data}, \"b\", \"e\")"; - List result = (List) FuncExecutor.getInstance().exec(ctxNode, funcExpression); - System.out.println(JSON.toJSONString(result)); - assertEquals(5, result.size()); - assertEquals(null, ((Map) result.get(1)).get("b")); - assertEquals(null, ((Map) result.get(1)).get("e")); - assertEquals(null, ((Map) result.get(3)).get("b")); - assertEquals(null, ((Map) result.get(3)).get("e")); - - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/MathFuncTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/MathFuncTests.java deleted file mode 100644 index 8f2f07d..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/MathFuncTests.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -import com.fizzgate.fizz.function.FuncExecutor; - -/** - * - * @author Francis Dong - * - */ -class MathFuncTests { - @Test - void contextLoads() { - } - - @Test - void testAbsExact() { - String funcExpression = "fn.math.absExact(-3)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(3, result); - } - - @Test - void testNegateExact() { - String funcExpression = "fn.math.negateExact(4)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(-4, result); - } - - @Test - void testNegateExact2() { - String funcExpression = "fn.math.negateExact(-4)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(4, result); - } - - @Test - void testAddExact() { - String funcExpression = "fn.math.addExact(14,-1)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(13, result); - } - - @Test - void testSubtractExact() { - String funcExpression = "fn.math.subtractExact(14,-1)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(15, result); - } - - @Test - void testMultiplyExact() { - String funcExpression = "fn.math.multiplyExact(14,2)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(28, result); - } - - @Test - void testMaxExact() { - String funcExpression = "fn.math.maxExact(14,2)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(14, result); - } - - @Test - void testMinExact() { - String funcExpression = "fn.math.minExact(14,2)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(2, result); - } - - @Test - void testMod() { - String funcExpression = "fn.math.mod(13,2)"; - long result = (long) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(1, result); - } - - @Test - void testPow() { - String funcExpression = "fn.math.pow(2,3)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(8, result); - } - - @Test - void testSqrt() { - String funcExpression = "fn.math.sqrt(4)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(2, result); - } - - @Test - void testAbsDecimal() { - String funcExpression = "fn.math.absDecimal(-4)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(4, result); - } - - @Test - void testNegateDecimal() { - String funcExpression = "fn.math.negateDecimal(4)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(-4, result); - } - - @Test - void testSubtractDecimal() { - String funcExpression = "fn.math.subtractDecimal(4,1.3)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(2.7, result); - } - - @Test - void testMultiplyDecimal() { - String funcExpression = "fn.math.multiplyDecimal(4,2.2)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(8.8, result); - } - - @Test - void testDivideDecimal() { - String funcExpression = "fn.math.divideDecimal(4.8,2)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(2.4, result); - } - - @Test - void testMaxDecimal() { - String funcExpression = "fn.math.maxDecimal(4.8,2)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(4.8, result); - } - - @Test - void testMinDecimal() { - String funcExpression = "fn.math.minDecimal(4.8,2)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(2, result); - } - - @Test - void testScaleDecimal() { - String funcExpression = "fn.math.scaleDecimal(4.8456,2)"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(4.85, result); - } - - @Test - void testRandom() { - String funcExpression = "fn.math.random()"; - double result = (double) FuncExecutor.getInstance().exec(null, funcExpression); - // System.out.println(result); - } - - @Test - void testcompare() { - String funcExpression = "fn.math.compare(4.8456,2)"; - int result = (int) FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(1, result); - } - - @Test - void testequals() { - String funcExpression = "fn.math.equals(3,3)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testLt() { - String funcExpression = "fn.math.lt(3,23)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testle() { - String funcExpression = "fn.math.le(3,3)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testgt() { - String funcExpression = "fn.math.gt(3,1)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testge() { - String funcExpression = "fn.math.ge(3,3)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/function/StringFuncTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/function/StringFuncTests.java deleted file mode 100644 index bf03b75..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/function/StringFuncTests.java +++ /dev/null @@ -1,224 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.fizzgate.fizz.function; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.function.FuncExecutor; -import com.fizzgate.fizz.input.PathMapping; - -/** - * - * @author Francis Dong - * - */ -class StringFuncTests { - - @Test - void contextLoads() { - } - - - @Test - void testEquals() { - String funcExpression = "fn.string.equals(\"abc\", \"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testEquals2() { - String funcExpression = "fn.string.equals(null, \"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(false, result); - } - - @Test - void testEquals3() { - String funcExpression = "fn.string.equals(\"ab\\\"c\", \"abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(false, result); - } - - @Test - void testEqualsIgnoreCase() { - String funcExpression = "fn.string.equalsIgnoreCase(\"abc\", \"Abc\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(true, result); - } - - @Test - void testcompare() { - String funcExpression = "fn.string.compare(\"abc\", \"cde\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals(-1, result); - } - - @Test - void testConcat() { - String funcExpression = "fn.string.concat(\"2021-07-09 22:44:55\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55", result.toString()); - } - - - @Test - void testConcat2() { - String funcExpression = "fn.string.concat(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\")"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55yyyy-MM-dd HH:mm:ss", result.toString()); - } - - @Test - void testConcat3() { - String funcExpression = "fn.string.concat(\"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\",1)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55yyyy-MM-dd HH:mm:ss1", result.toString()); - } - - @Test - void testConcatws() { - String funcExpression = "fn.string.concatws(\",\" , \"2021-07-09 22:44:55\", \"yyyy-MM-dd HH:mm:ss\" )"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55,yyyy-MM-dd HH:mm:ss", result.toString()); - } - - @Test - void testSubstring() { - String funcExpression = "fn.string.substring(\"2021-07-09 22:44:55\", 1 , 4)"; - Object result = FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55".substring(1, 4), result.toString()); - } - - @Test - void testSubstring2() { - ONode ctxNode = ONode.load(new HashMap()); - - Map m = new HashMap<>(); - m.put("a", "1"); - m.put("b", "1"); - - PathMapping.setByPath(ctxNode, "data.dateStr", "2021-07-09 22:44:55", true); - PathMapping.setByPath(ctxNode, "data.startIndex", 1, true); - PathMapping.setByPath(ctxNode, "data", m, false); - - String funcExpression = "fn.string.substring({data.dateStr}, {data.startIndex})"; -// String funcExpression = "fn.string.substring(\"2021-07-09 22:44:55\", 1)"; - Object result = FuncExecutor.getInstance().exec(ctxNode, funcExpression); - System.out.println(result); - assertEquals("2021-07-09 22:44:55".substring(1), result.toString()); - } - - @Test - void testIndexOf() { - String funcExpression = "fn.string.indexOf(\"2021-07-09 22:44:55\", \"07\")"; - int result = (int)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55".indexOf("07"), result); - } - - @Test - void testStartsWith() { - String funcExpression = "fn.string.startsWith(\"2021-07-09 22:44:55\", \"2021\")"; - boolean result = (boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55".startsWith("2021"), result); - } - - @Test - void testEndsWith() { - String funcExpression = "fn.string.endsWith(\"2021-07-09 22:44:55\", \"44:55\")"; - boolean result = (boolean)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55".endsWith("44:55"), result); - } - - @Test - void testToUpperCase() { - String funcExpression = "fn.string.toUpperCase(\"aBc\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("aBc".toUpperCase(), result); - } - - @Test - void testToLowerCase() { - String funcExpression = "fn.string.toLowerCase(\"aBc\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("aBc".toLowerCase(), result); - } - - @Test - void testToString() { - String funcExpression = "fn.string.toString(\"aBc\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("aBc", result); - } - - @Test - void testToString2() { - String funcExpression = "fn.string.toString(true)"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("true", result); - } - - @Test - void testToString3() { - String funcExpression = "fn.string.toString(234)"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("234", result); - } - - - @Test - void testToString4() { - String funcExpression = "fn.string.toString(fn.date.timestamp())"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - System.out.println(result); - } - - @Test - void testReplace() { - String funcExpression = "fn.string.replace(\"2021-07-09 22:44:55\", \"44:55\", \"00:00\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55".replace("44:55", "00:00"), result); - } - - @Test - void testReplaceAll() { - String funcExpression = "fn.string.replaceAll(\"2021-07-09 22:44:55 44:55\", \"44:55\", \"00:00\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55 44:55".replaceAll("44:55", "00:00"), result); - } - - @Test - void testReplaceAll2() { - String funcExpression = "fn.string.replaceAll(\"1.2.3\", \"\\.\", \"\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("1.2.3".replaceAll("\\.", ""), result); - } - - @Test - void testReplaceFirst() { - String funcExpression = "fn.string.replaceFirst(\"2021-07-09 22:44:55 44:55\", \"44:55\", \"00:00\")"; - String result = (String)FuncExecutor.getInstance().exec(null, funcExpression); - assertEquals("2021-07-09 22:44:55 44:55".replaceFirst("44:55", "00:00"), result); - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/group/DevTestGroup.java b/fizz-core/src/test/java/com/fizzgate/fizz/group/DevTestGroup.java deleted file mode 100644 index ed1136a..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/group/DevTestGroup.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.fizzgate.fizz.group; - -public class DevTestGroup { -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/group/FastTestGroup.java b/fizz-core/src/test/java/com/fizzgate/fizz/group/FastTestGroup.java deleted file mode 100644 index 3ce12ef..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/group/FastTestGroup.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.fizzgate.fizz.group; - -public class FastTestGroup { -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/group/SlowTestGroup.java b/fizz-core/src/test/java/com/fizzgate/fizz/group/SlowTestGroup.java deleted file mode 100644 index 06d07d8..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/group/SlowTestGroup.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.fizzgate.fizz.group; - -public class SlowTestGroup { -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/DubboInputMockTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/DubboInputMockTests.java deleted file mode 100644 index 8d01626..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/DubboInputMockTests.java +++ /dev/null @@ -1,90 +0,0 @@ -package com.fizzgate.fizz.input; - -import org.apache.dubbo.config.ReferenceConfig; -import org.apache.dubbo.rpc.service.GenericService; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import org.springframework.context.ConfigurableApplicationContext; - -import com.fizzgate.fizz.Step; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.StepResponse; -import com.fizzgate.fizz.group.FastTestGroup; -import com.fizzgate.fizz.input.InputContext; -import com.fizzgate.fizz.input.InputFactory; -import com.fizzgate.fizz.input.extension.dubbo.DubboInput; -import com.fizzgate.fizz.input.extension.dubbo.DubboInputConfig; -import com.fizzgate.proxy.dubbo.ApacheDubboGenericService; -import com.fizzgate.proxy.dubbo.DubboInterfaceDeclaration; - -import java.lang.ref.SoftReference; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -@RunWith(MockitoJUnitRunner.class) -@Category(FastTestGroup.class) -public class DubboInputMockTests { - private static final String SERVICE_NAME = "com.fizzgate.test"; - private static final String METHOD_NAME = "method"; - private static final String[] LEFT = new String[]{}; - - private static final Object[] RIGHT = new Object[]{}; - - private ApacheDubboGenericService proxy; -// @Before -// public void setup(){ -// ApacheDubboGenericProxyTests test = new ApacheDubboGenericProxyTests(); -// proxy = test.getMockApachDubbo(); -// } - - @Test - public void test() { - DubboInterfaceDeclaration declaration = new DubboInterfaceDeclaration(); - declaration.setServiceName(SERVICE_NAME); - declaration.setMethod(METHOD_NAME); - declaration.setParameterTypes("java.lang.String, java.lang.String"); - declaration.setTimeout(3000); - - ReferenceConfig referenceConfig = mock(ReferenceConfig.class); - GenericService genericService = mock(GenericService.class); - when(referenceConfig.get()).thenReturn(genericService); - when(referenceConfig.getInterface()).thenReturn(SERVICE_NAME); - CompletableFuture future = new CompletableFuture<>(); - when(genericService.$invokeAsync(any(), any(), any())).thenReturn(future); - ApacheDubboGenericService apacheDubboProxyService = new ApacheDubboGenericService(); - ApacheDubboGenericService proxy = spy(apacheDubboProxyService); - when(proxy.createReferenceConfig(SERVICE_NAME, null, null)).thenReturn(referenceConfig); - - ConfigurableApplicationContext applicationContext = mock(ConfigurableApplicationContext.class); - when(applicationContext.getBean(ApacheDubboGenericService.class)).thenReturn(proxy); - - Step step = mock(Step.class); - when(step.getCurrentApplicationContext()).thenReturn(applicationContext); - - StepResponse stepResponse = new StepResponse(step, null, new HashMap>()); - DubboInputConfig config = mock(DubboInputConfig.class); - when(config.getServiceName()).thenReturn(SERVICE_NAME); - InputFactory.registerInput(DubboInput.TYPE, DubboInput.class); - DubboInput dubboInput = (DubboInput)InputFactory.createInput(DubboInput.TYPE.toString()); - - dubboInput.setName("input1"); - dubboInput.setWeakStep(new SoftReference<>(step)); - dubboInput.setStepResponse(stepResponse); - dubboInput.setConfig(config); - StepContext stepContext = mock(StepContext.class); - stepContext.put("step1", stepResponse); - InputContext context = new InputContext(stepContext, null); - dubboInput.beforeRun(context); - - dubboInput.run(); - - future.complete("success"); - - } -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/DubboInputTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/DubboInputTests.java deleted file mode 100644 index 740c6bf..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/DubboInputTests.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.fizzgate.fizz.input; - -import org.junit.experimental.categories.Category; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.context.ActiveProfiles; - -import com.fizzgate.fizz.group.DevTestGroup; -import com.fizzgate.fizz.input.extension.dubbo.DubboInput; -import com.fizzgate.fizz.input.extension.dubbo.DubboInputConfig; - -import reactor.core.publisher.Mono; - -import java.util.HashMap; -import java.util.Map; - - -@ActiveProfiles("") -//@SpringBootTest -@Category(DevTestGroup.class) -class DubboInputTests { - private static final String SERVICE_NAME = "com.fizzgate.fizz.examples.dubbo.common.service.UserService"; - private static final String METHOD_NAME = "findAll"; - //@Test - public void test() { - - Map requestConfig = new HashMap(); - requestConfig.put("serviceName",SERVICE_NAME); - requestConfig.put("method",METHOD_NAME); -// requestConfig.put("parameterTypes", "java.lang.String"); - - DubboInputConfig inputConfig = new DubboInputConfig(requestConfig); - inputConfig.parse(); - DubboInput input = new DubboInput(); - input.setConfig(inputConfig); - input.beforeRun(null); - Monomono = input.run(); - Map result = mono.block(); - System.out.print(result); - Assertions.assertNotEquals(result, null, "no response"); - - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/GrpcInputMockTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/GrpcInputMockTests.java deleted file mode 100644 index 30f89a9..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/GrpcInputMockTests.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.fizzgate.fizz.input; - -import com.fizzgate.fizz.Step; -import com.fizzgate.fizz.StepContext; -import com.fizzgate.fizz.StepResponse; -import com.fizzgate.fizz.group.FastTestGroup; -import com.fizzgate.fizz.input.InputContext; -import com.fizzgate.fizz.input.InputFactory; -import com.fizzgate.fizz.input.extension.grpc.GrpcInput; -import com.fizzgate.fizz.input.extension.grpc.GrpcInputConfig; -import com.fizzgate.proxy.grpc.GrpcGenericService; -import com.fizzgate.proxy.grpc.GrpcInterfaceDeclaration; -import com.fizzgate.proxy.grpc.client.GrpcProxyClient; -import com.fizzgate.proxy.grpc.client.utils.ChannelFactory; -import com.google.common.util.concurrent.ListenableFuture; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.test.util.ReflectionTestUtils; - -import java.lang.ref.SoftReference; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.*; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - -@RunWith(MockitoJUnitRunner.class) -@Category(FastTestGroup.class) -public class GrpcInputMockTests { - private static final String URL ="localhost:8090"; - private static final String SERVICE_NAME = "com.fizzgate.test"; - private static final String METHOD_NAME = "method"; - private static final String[] LEFT = new String[]{}; - - private static final Object[] RIGHT = new Object[]{}; - - private GrpcGenericService proxy; -// @Before -// public void setup(){ -// ApacheDubboGenericProxyTests test = new ApacheDubboGenericProxyTests(); -// proxy = test.getMockApachDubbo(); -// } - - @Test - public void test() { - mockStatic(ChannelFactory.class); - GrpcInterfaceDeclaration declaration = new GrpcInterfaceDeclaration(); - declaration.setEndpoint(URL); - declaration.setServiceName(SERVICE_NAME); - declaration.setMethod(METHOD_NAME); - declaration.setTimeout(3000); - - GrpcProxyClient grpcProxyClient = mock(GrpcProxyClient.class); - - ListenableFuture future = new ListenableFuture() { - @Override - public boolean cancel(boolean mayInterruptIfRunning) { - return false; - } - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return false; - } - - @Override - public String get() throws InterruptedException, ExecutionException { - return "result"; - } - - @Override - public String get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { - return null; - } - - @Override - public void addListener(Runnable runnable, Executor executor) { - - } - }; - when(grpcProxyClient.invokeMethodAsync(any(), any(), any(), any(), any())).thenReturn((ListenableFuture) future); - - GrpcGenericService grpcGenericService = new GrpcGenericService(); - ReflectionTestUtils.setField(grpcGenericService, "grpcProxyClient", grpcProxyClient); - - ConfigurableApplicationContext applicationContext = mock(ConfigurableApplicationContext.class); - when(applicationContext.getBean(GrpcGenericService.class)).thenReturn(grpcGenericService); - - Step step = mock(Step.class); - when(step.getCurrentApplicationContext()).thenReturn(applicationContext); - - StepResponse stepResponse = new StepResponse(step, null, new HashMap>()); - GrpcInputConfig config = mock(GrpcInputConfig.class); - when(config.getServiceName()).thenReturn(SERVICE_NAME); - InputFactory.registerInput(GrpcInput.TYPE, GrpcInput.class); - GrpcInput grpcInput = (GrpcInput)InputFactory.createInput(GrpcInput.TYPE.toString()); - HashMap request = new HashMap (); - request.put("url",URL); - ReflectionTestUtils.setField(grpcInput, "request", request); - grpcInput.setName("input1"); - grpcInput.setWeakStep(new SoftReference<>(step)); - grpcInput.setStepResponse(stepResponse); - grpcInput.setConfig(config); - StepContext stepContext = mock(StepContext.class); - stepContext.put("step1", stepResponse); - InputContext context = new InputContext(stepContext, null); - grpcInput.beforeRun(context); - - grpcInput.run(); - - - } -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/PathMappingTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/PathMappingTests.java deleted file mode 100644 index 0c96983..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/PathMappingTests.java +++ /dev/null @@ -1,226 +0,0 @@ -package com.fizzgate.fizz.input; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import org.noear.snack.ONode; - -import com.fizzgate.fizz.input.PathMapping; -import com.fizzgate.global_resource.GlobalResourceService; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; - - -class PathMappingTests { - @Test - void contextLoads() { - } - - @Test - void testSetByPath() { - - ONode target = ONode.load(new HashMap()); - - Map m = new HashMap<>(); - m.put("a", "1"); - m.put("b", "1"); - - PathMapping.setByPath(target, "data.id", "2", true); - PathMapping.setByPath(target, "data", m, false); - - assertEquals("1", target.get("data").get("a").getString()); - assertEquals("1", target.get("data").get("b").getString()); - assertEquals("2", target.get("data").get("id").getString()); - - - List list = new ArrayList<>(); - list.add("YYYY"); - PathMapping.setByPath(target, "data.zzz", list, true); - - List list2 = new ArrayList<>(); - list2.add("XXXX"); - PathMapping.setByPath(target, "data.zzz", list2, true); - - - List actualList = (List) target.get("data").get("zzz").toData(); - assertTrue(actualList.contains("YYYY")); - assertTrue(actualList.contains("XXXX")); - - - List list3 = new ArrayList<>(); - list3.add("vvvv"); - PathMapping.setByPath(target, "data.ppp", list3, true); - - - Map m3 = new HashMap<>(); - m3.put("sss", "sss"); - PathMapping.setByPath(target, "data.ppp", m3, true); - - List list4 = new ArrayList<>(); - list4.add("kkk"); - PathMapping.setByPath(target, "data.ppp", list4, true); - - List actualList2 = (List) target.get("data").get("ppp").toData(); - assertTrue(actualList2.contains("kkk")); - - - } - - - @Test - void testHandlePath() { - LinkedHashMap pathMap = new LinkedHashMap<>(); - pathMap.put("step1.request1.request.headers", "step1.requests.request1.request.headers"); - pathMap.put("step1.request1.requestHeaders", "step1.requests.request1.request.headers"); - pathMap.put("step1.requests.request1.requestHeaders", "step1.requests.request1.request.headers"); - - pathMap.put("step1.request1.request.params", "step1.requests.request1.request.params"); - pathMap.put("step1.request1.requestParams", "step1.requests.request1.request.params"); - pathMap.put("step1.requests.request1.requestParams", "step1.requests.request1.request.params"); - - pathMap.put("step1.request1.request.body", "step1.requests.request1.request.body"); - pathMap.put("step1.request1.requestBody", "step1.requests.request1.request.body"); - pathMap.put("step1.requests.request1.requestBody", "step1.requests.request1.request.body"); - - pathMap.put("step1.request1.response.headers", "step1.requests.request1.response.headers"); - pathMap.put("step1.request1.responseHeaders", "step1.requests.request1.response.headers"); - pathMap.put("step1.requests.request1.responseHeaders", "step1.requests.request1.response.headers"); - - pathMap.put("step1.request1.response.body", "step1.requests.request1.response.body"); - pathMap.put("step1.request1.responseBody", "step1.requests.request1.response.body"); - pathMap.put("step1.requests.request1.responseBody", "step1.requests.request1.response.body"); - - pathMap.put("input.requestHeaders", "input.request.headers"); - pathMap.put("input.requestParams", "input.request.params"); - pathMap.put("input.requestBody", "input.request.body"); - pathMap.put("input.responseHeaders", "input.response.headers"); - pathMap.put("input.responseBody", "input.response.body"); - - pathMap.put("step1.request1.request.headers.Aa", "step1.requests.request1.request.headers.AA"); - pathMap.put("step1.request1.response.headers.aa", "step1.requests.request1.response.headers.AA"); - pathMap.put("input.requestHeaders.aa", "input.request.headers.AA"); - pathMap.put("input.responseHeaders.aA", "input.response.headers.AA"); - - - for (Entry entry : pathMap.entrySet()) { - Assertions.assertEquals(entry.getValue(), PathMapping.handlePath(entry.getKey())); - } - } - - @Test - void testSelect() { - Map m = new HashMap<>(); - ONode ctxNode = PathMapping.toONode(m); - PathMapping.setByPath(ctxNode, "step1.requests.request1.request.headers.abc", "1", true); - PathMapping.setByPath(ctxNode, "step1.requests.request1.request.headers.name1", "ken", true); - PathMapping.setByPath(ctxNode, "input.request.headers.abc", "1", true); - PathMapping.setByPath(ctxNode, "input.request.headers.name1", "ken", true); - List vals = new ArrayList<>(); - vals.add("Ken"); - vals.add("Kelly"); - PathMapping.setByPath(ctxNode, "step1.requests.request1.request.headers.name2", vals, true); - PathMapping.setByPath(ctxNode, "input.request.headers.name2", vals, true); - - - - ONode abc = PathMapping.select(ctxNode, "step1.requests.request1.request.headers.abc"); - ONode name1 = PathMapping.select(ctxNode, "step1.requests.request1.request.headers.name1"); - ONode inputAbc = PathMapping.select(ctxNode, "input.request.headers.abc"); - ONode inputAbcName1 = PathMapping.select(ctxNode, "input.request.headers.name1"); - ONode name2 = PathMapping.select(ctxNode, "step1.requests.request1.request.headers.name2"); - ONode inputAbcName2 = PathMapping.select(ctxNode, "input.request.headers.name2"); - assertEquals("1", (String)abc.toData()); - assertEquals("ken", (String)name1.toData()); - assertEquals("1", (String)inputAbc.toData()); - assertEquals("ken", (String)inputAbcName1.toData()); - assertEquals(2, ((List)name2.toData()).size()); - assertEquals(2, ((List)inputAbcName2.toData()).size()); - - abc = PathMapping.select(ctxNode, "step1.requests.request1.request.headers.abc[0]"); - name1 = PathMapping.select(ctxNode, "step1.requests.request1.request.headers.name1[0]"); - inputAbc = PathMapping.select(ctxNode, "input.request.headers.abc[0]"); - inputAbcName1 = PathMapping.select(ctxNode, "input.request.headers.name1[0]"); - name2 = PathMapping.select(ctxNode, "step1.requests.request1.request.headers.name2[0]"); - inputAbcName2 = PathMapping.select(ctxNode, "input.request.headers.name2[0]"); - assertEquals("1", (String)abc.toData()); - assertEquals("ken", (String)name1.toData()); - assertEquals("1", (String)inputAbc.toData()); - assertEquals("ken", (String)inputAbcName1.toData()); - assertEquals("Ken", (String)name2.toData()); - assertEquals("Ken", (String)inputAbcName2.toData()); - - PathMapping.setByPath(ctxNode, "step1.requests.request1.request.headers.TEST", "1", true); - Object abcVal1 = PathMapping.getValueByPath(ctxNode, "step1.requests.request1.request.headers.test[0]|123"); - Object abcVal2 = PathMapping.getValueByPath(ctxNode, "step1.requests.request1.request.headers.test[3]|123456"); - assertEquals("1", (String)abcVal1); - assertEquals("123456", (String)abcVal2); - - } - - - @Test - void testArray() { - ONode ctxNode = ONode.load(new HashMap()); - - Map m = new HashMap<>(); - m.put("a", "1"); - m.put("b", "1"); - - List list = new ArrayList<>(); - list.add("0"); - list.add("1"); - list.add("2"); - list.add("3"); - list.add("4"); - - PathMapping.setByPath(ctxNode, "data.m", m, true); - - PathMapping.setByPath(ctxNode, "data.arr", list, true); - - Object abcVal1 = PathMapping.getValueByPath(ctxNode, "data.arr[0]"); - assertEquals("0", (String)abcVal1); - Object abcVal2 = PathMapping.getValueByPath(ctxNode, "data.arr[-1]"); - assertEquals("4", (String)abcVal2); - } - - @Test - void testGlobalResource() { - ONode resNode = ONode.load(new HashMap()); - - Map m = new HashMap<>(); - m.put("a", "1"); - m.put("b", "1"); - - List list = new ArrayList<>(); - list.add("0"); - list.add("1"); - list.add("2"); - list.add("3"); - list.add("4"); - - - PathMapping.setByPath(resNode, "data.m", m, true); - - PathMapping.setByPath(resNode, "data.arr", list, true); - - GlobalResourceService.resNode = resNode; - - ONode emptyCtx = ONode.load(new HashMap()); - - Object abcVal1 = PathMapping.getValueByPath(emptyCtx, "g.data.arr[0]"); - assertEquals("0", (String)abcVal1); - Object abcVal2 = PathMapping.getValueByPath(emptyCtx, "g.data.arr[-1]"); - assertEquals("4", (String)abcVal2); - } - -} \ No newline at end of file diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/RequestInputTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/RequestInputTests.java deleted file mode 100644 index d60aaa4..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/RequestInputTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2021 the original author or authors. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.fizzgate.fizz.input; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import com.fizzgate.fizz.input.extension.request.RequestInput; - -/** - * - * @author Francis Dong - * - */ -public class RequestInputTests { - - @Test - public void testParseBody() { - - // test json and text - String[] contentTypes = new String[] { "application/json; charset=UTF-8", "application/json;", - "application/json", "text/plain" }; - - String[] respBodys = new String[] { "{\"a\":\"b\"}", "[{\"a\":\"b\"}]" }; - - RequestInput requestInput = new RequestInput(); - for (int n = 0; n < respBodys.length; n++) { - String respBody = respBodys[n]; - for (int i = 0; i < contentTypes.length; i++) { - String ct = contentTypes[i]; - Object body = requestInput.parseBody(ct, respBody); - assertEquals(respBody, body.toString()); - } - } - - // test invalid text content - contentTypes = new String[] { "text/plain" }; - respBodys = new String[] { "{\"a\":\"b\"", "{\"a\":\"b\"}]" }; - for (int n = 0; n < respBodys.length; n++) { - String respBody = respBodys[n]; - for (int i = 0; i < contentTypes.length; i++) { - String ct = contentTypes[i]; - Object body = requestInput.parseBody(ct, respBody); - assertEquals(respBody, body.toString()); - } - } - - // test html js - contentTypes = new String[] {"application/javascript", "text/html"}; - respBodys = new String[] { "{\"a\":\"b\"", "{\"a\":\"b\"}]", "var a=1;" , "" }; - for (int n = 0; n < respBodys.length; n++) { - String respBody = respBodys[n]; - for (int i = 0; i < contentTypes.length; i++) { - String ct = contentTypes[i]; - Object body = requestInput.parseBody(ct, respBody); - assertEquals(respBody, body.toString()); - } - } - - // test xml - String xmlBody = "123"; - Map> root = (Map>) requestInput - .parseBody("application/xml", xmlBody); - Map m = root.get("person"); - assertEquals("b", m.get("-a")); - assertEquals("123", m.get("#text")); - } - -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/proxy/dubbo/ApacheDubboGenericServiceMockTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/proxy/dubbo/ApacheDubboGenericServiceMockTests.java deleted file mode 100644 index 37548f6..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/proxy/dubbo/ApacheDubboGenericServiceMockTests.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.fizzgate.fizz.input.proxy.dubbo; - -import org.apache.dubbo.config.ReferenceConfig; -import org.apache.dubbo.rpc.service.GenericService; - -import org.junit.Before; -import org.junit.Test; -import org.junit.experimental.categories.Category; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import com.fizzgate.fizz.group.FastTestGroup; -import com.fizzgate.proxy.dubbo.ApacheDubboGenericService; -import com.fizzgate.proxy.dubbo.DubboInterfaceDeclaration; - -import java.util.HashMap; -import java.util.concurrent.CompletableFuture; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) -@Category(FastTestGroup.class) -public class ApacheDubboGenericServiceMockTests { - private static final String SERVICE_NAME = "com.fizzgate.test"; - private static final String METHOD_NAME = "method"; - private static final String[] LEFT = new String[]{}; - - private static final Object[] RIGHT = new Object[]{}; - @Before - public void setup(){ - - } - - public ApacheDubboGenericService getMockApachDubbo(){ - ReferenceConfig referenceConfig = mock(ReferenceConfig.class); - GenericService genericService = mock(GenericService.class); - when(referenceConfig.get()).thenReturn(genericService); - when(referenceConfig.getInterface()).thenReturn(SERVICE_NAME); - ApacheDubboGenericService apacheDubboProxyService = mock(ApacheDubboGenericService.class); - when(apacheDubboProxyService.createReferenceConfig(SERVICE_NAME, null, null)).thenReturn(referenceConfig); - CompletableFuture future = new CompletableFuture<>(); - when(genericService.$invokeAsync(METHOD_NAME, LEFT, RIGHT)).thenReturn(future); - future.complete("success"); - return apacheDubboProxyService; - } - @Test - public void test() { - HashMap attachments = mock(HashMap.class); - DubboInterfaceDeclaration declaration = mock(DubboInterfaceDeclaration.class); - declaration.setServiceName(SERVICE_NAME); - declaration.setMethod(METHOD_NAME); - declaration.setParameterTypes("java.lang.String, java.lang.String"); - declaration.setTimeout(3000); - ApacheDubboGenericServiceMockTests test = new ApacheDubboGenericServiceMockTests(); - ApacheDubboGenericService apacheDubboProxyService = test.getMockApachDubbo(); - apacheDubboProxyService.send(null, declaration, attachments); - } - -} diff --git a/fizz-core/src/test/java/com/fizzgate/fizz/input/proxy/dubbo/ApacheDubboGenericServiceTests.java b/fizz-core/src/test/java/com/fizzgate/fizz/input/proxy/dubbo/ApacheDubboGenericServiceTests.java deleted file mode 100644 index 3de5d90..0000000 --- a/fizz-core/src/test/java/com/fizzgate/fizz/input/proxy/dubbo/ApacheDubboGenericServiceTests.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.fizzgate.fizz.input.proxy.dubbo; - -import org.apache.dubbo.config.ReferenceConfig; -import org.apache.dubbo.rpc.service.GenericService; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.junit.MockitoJUnitRunner; - -import com.fizzgate.proxy.dubbo.ApacheDubboGenericService; -import com.fizzgate.proxy.dubbo.DubboInterfaceDeclaration; - -import java.util.HashMap; -import java.util.concurrent.CompletableFuture; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) -public class ApacheDubboGenericServiceTests { - private static final String SERVICE_NAME = "com.fizzgate.test"; - private static final String METHOD_NAME = "method"; - private static final String[] LEFT = new String[]{}; - - private static final Object[] RIGHT = new Object[]{}; - @Before - public void setup(){ - - } - - public ApacheDubboGenericService getMockApachDubbo(){ - ReferenceConfig referenceConfig = mock(ReferenceConfig.class); - GenericService genericService = mock(GenericService.class); - when(referenceConfig.get()).thenReturn(genericService); - when(referenceConfig.getInterface()).thenReturn(SERVICE_NAME); - ApacheDubboGenericService apacheDubboProxyService = mock(ApacheDubboGenericService.class); - when(apacheDubboProxyService.createReferenceConfig(SERVICE_NAME, null, null)).thenReturn(referenceConfig); - CompletableFuture future = new CompletableFuture<>(); - when(genericService.$invokeAsync(METHOD_NAME, LEFT, RIGHT)).thenReturn(future); - future.complete("success"); - return apacheDubboProxyService; - } - @Test - public void test() { - HashMap attachments = mock(HashMap.class); - DubboInterfaceDeclaration declaration = mock(DubboInterfaceDeclaration.class); - declaration.setServiceName(SERVICE_NAME); - declaration.setMethod(METHOD_NAME); - declaration.setParameterTypes("java.lang.String, java.lang.String"); - declaration.setTimeout(3000); - ApacheDubboGenericServiceTests test = new ApacheDubboGenericServiceTests(); - ApacheDubboGenericService apacheDubboProxyService = test.getMockApachDubbo(); - apacheDubboProxyService.send(null, declaration, attachments); - } - -} diff --git a/fizz-core/src/test/java/com/fizzgate/proxy/CallbackServiceTests.java b/fizz-core/src/test/java/com/fizzgate/proxy/CallbackServiceTests.java index b0e16e4..3c7b6d0 100644 --- a/fizz-core/src/test/java/com/fizzgate/proxy/CallbackServiceTests.java +++ b/fizz-core/src/test/java/com/fizzgate/proxy/CallbackServiceTests.java @@ -1,5 +1,6 @@ package com.fizzgate.proxy; +import com.fizzgate.aggregate.web.service.AggregateService; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.core.io.buffer.DataBuffer; @@ -12,7 +13,6 @@ import org.springframework.mock.web.server.MockServerWebExchange; import org.springframework.web.reactive.function.client.ClientResponse; import org.springframework.web.reactive.function.client.ExchangeStrategies; -import com.fizzgate.fizz.AggregateService; import com.fizzgate.plugin.auth.ApiConfig; import com.fizzgate.plugin.auth.ApiConfigService; import com.fizzgate.plugin.auth.CallbackConfig; diff --git a/fizz-plugin/src/test/java/com/fizzgate/plugin/grayrelease/GrayReleasePluginTests.java b/fizz-plugin/src/test/java/com/fizzgate/plugin/grayrelease/GrayReleasePluginTests.java index 655c993..ca2d909 100644 --- a/fizz-plugin/src/test/java/com/fizzgate/plugin/grayrelease/GrayReleasePluginTests.java +++ b/fizz-plugin/src/test/java/com/fizzgate/plugin/grayrelease/GrayReleasePluginTests.java @@ -1,12 +1,9 @@ package com.fizzgate.plugin.grayrelease; import com.fasterxml.jackson.core.type.TypeReference; -import com.fizzgate.filter.AggregateFilter; import com.fizzgate.filter.FilterResult; -import com.fizzgate.fizz.ConfigLoader; import com.fizzgate.plugin.FizzPluginFilterChain; import com.fizzgate.plugin.auth.ApiConfig; -import com.fizzgate.plugin.grayrelease.GrayReleasePlugin; import com.fizzgate.proxy.Route; import com.fizzgate.util.Consts; import com.fizzgate.util.JacksonUtils; diff --git a/fizz-spring-boot-starter/src/main/resources/META-INF/spring.factories b/fizz-spring-boot-starter/src/main/resources/META-INF/spring.factories index dcba522..ee1636c 100644 --- a/fizz-spring-boot-starter/src/main/resources/META-INF/spring.factories +++ b/fizz-spring-boot-starter/src/main/resources/META-INF/spring.factories @@ -1,7 +1,6 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.fizzgate.config.AggregateRedisConfig,\ com.fizzgate.config.ApolloConfig,\ -com.fizzgate.config.AppConfigProperties,\ com.fizzgate.config.FlowControlConfig,\ com.fizzgate.config.FlowStatSchedConfig,\ com.fizzgate.config.ProxyWebClientConfig,\ @@ -15,17 +14,12 @@ com.fizzgate.controller.CallbackController,\ com.fizzgate.controller.ConfigController,\ com.fizzgate.controller.FlowControlController,\ com.fizzgate.controller.ManagerConfigController,\ -com.fizzgate.filter.AggregateFilter,\ com.fizzgate.filter.CallbackFilter,\ com.fizzgate.filter.CorsFilterConfig,\ -com.fizzgate.filter.FilterExceptionHandlerConfig,\ com.fizzgate.filter.FizzLogFilter,\ com.fizzgate.filter.FlowControlFilter,\ com.fizzgate.filter.PreprocessFilter,\ com.fizzgate.filter.RouteFilter,\ -com.fizzgate.fizz.AggregateService,\ -com.fizzgate.fizz.ConfigLoader,\ -com.fizzgate.listener.AggregateChannelListener,\ com.fizzgate.plugin.auth.ApiConfigService,\ com.fizzgate.plugin.auth.ApiConfig2appsService,\ com.fizzgate.plugin.auth.AppService,\