1. 新增外部系统编码部门编码关联管理
2. 新增统一的 api 对外门户管理 3. 修正各个模块的 api 命名
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
package com.zt.plat.module.databus.controller.admin.gateway;
|
||||
|
||||
import com.zt.plat.module.databus.controller.admin.gateway.vo.ApiGatewayInvokeReqVO;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.core.ApiGatewayExecutionService;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.model.ApiGatewayResponse;
|
||||
import com.zt.plat.module.databus.service.gateway.ApiDefinitionService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@WebMvcTest(ApiGatewayController.class)
|
||||
@AutoConfigureMockMvc(addFilters = false)
|
||||
@TestPropertySource(properties = {
|
||||
"spring.config.import=optional:",
|
||||
"spring.cloud.nacos.config.enabled=false",
|
||||
"spring.cloud.nacos.discovery.enabled=false"
|
||||
})
|
||||
class ApiGatewayControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
private ApiGatewayExecutionService executionService;
|
||||
|
||||
@MockBean
|
||||
private ApiDefinitionService apiDefinitionService;
|
||||
|
||||
@Test
|
||||
void invokeShouldReturnGatewayEnvelope() throws Exception {
|
||||
ApiGatewayResponse response = ApiGatewayResponse.builder()
|
||||
.code(200)
|
||||
.message("OK")
|
||||
.response(Map.of("code", 0))
|
||||
.traceId("trace-123")
|
||||
.build();
|
||||
when(executionService.invokeForDebug(any(ApiGatewayInvokeReqVO.class)))
|
||||
.thenReturn(ResponseEntity.ok(response));
|
||||
|
||||
mockMvc.perform(post("/databus/gateway/invoke")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("{\"apiCode\":\"demo\",\"version\":\"v1\"}"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.code").value(200))
|
||||
.andExpect(jsonPath("$.message").value("OK"))
|
||||
.andExpect(jsonPath("$.response.code").value(0))
|
||||
.andExpect(jsonPath("$.traceId").value("trace-123"));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,56 @@
|
||||
package com.zt.plat.module.databus.framework.integration.gateway.policy;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.security.GatewayJwtResolver;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class DefaultAuthPolicyEvaluatorTest {
|
||||
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
void shouldResolveTokenFromPrimaryHeader() {
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.put(GatewayJwtResolver.HEADER_ZT_AUTH_TOKEN, List.of(" token-123 "));
|
||||
|
||||
String token = GatewayJwtResolver.resolveJwtToken(headers, Map.of(), objectMapper);
|
||||
|
||||
assertThat(token).isEqualTo("token-123");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFallbackToAuthorizationHeader() {
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.put("Authorization", "Bearer token-456");
|
||||
|
||||
String token = GatewayJwtResolver.resolveJwtToken(headers, Map.of(), objectMapper);
|
||||
|
||||
assertThat(token).isEqualTo("token-456");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldParseTokenFromStructuredPayload() {
|
||||
Map<String, Object> headers = new HashMap<>();
|
||||
headers.put("Authorization", List.of("", "{\"token\":\"abc-789\"}"));
|
||||
|
||||
String token = GatewayJwtResolver.resolveJwtToken(headers, Map.of(), objectMapper);
|
||||
|
||||
assertThat(token).isEqualTo("abc-789");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldUseQueryParameterAsLastResort() {
|
||||
Map<String, Object> headers = Map.of();
|
||||
Map<String, Object> queryParams = Map.of("token", " token-999 ");
|
||||
|
||||
String token = GatewayJwtResolver.resolveJwtToken(headers, queryParams, objectMapper);
|
||||
|
||||
assertThat(token).isEqualTo("token-999");
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,99 @@
|
||||
package com.zt.plat.module.databus.framework.integration.gateway.step.impl;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.zt.plat.framework.common.exception.ServiceException;
|
||||
import com.zt.plat.module.databus.dal.dataobject.gateway.ApiStepDO;
|
||||
import com.zt.plat.module.databus.enums.gateway.ExpressionTypeEnum;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.domain.ApiDefinitionAggregate;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.domain.ApiStepDefinition;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.expression.ExpressionEvaluatorRegistry;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.expression.ExpressionExecutor;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.expression.JsonataExpressionEvaluator;
|
||||
import com.zt.plat.module.databus.framework.integration.gateway.model.ApiInvocationContext;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.integration.core.GenericHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.zt.plat.module.databus.service.gateway.impl.GatewayServiceErrorCodeConstants.API_STEP_START_EXECUTION_FAILED;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class StartStepHandlerTest {
|
||||
|
||||
private StartStepHandler handler;
|
||||
private ApiDefinitionAggregate aggregate;
|
||||
|
||||
private static MessageHeaders emptyHeaders() {
|
||||
return new MessageHeaders(Collections.emptyMap());
|
||||
}
|
||||
|
||||
private static ObjectMapper createObjectMapper() {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
mapper.registerModule(new JavaTimeModule());
|
||||
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
|
||||
return mapper;
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
ExpressionEvaluatorRegistry registry = new ExpressionEvaluatorRegistry();
|
||||
registry.register(ExpressionTypeEnum.JSON, new JsonataExpressionEvaluator(createObjectMapper()));
|
||||
handler = new StartStepHandler(new ExpressionExecutor(registry));
|
||||
aggregate = ApiDefinitionAggregate.builder().build();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldApplyRequestMappingsToInvocationContext() {
|
||||
ApiStepDO stepDO = new ApiStepDO();
|
||||
stepDO.setId(101L);
|
||||
stepDO.setType("START");
|
||||
stepDO.setRequestMappingExpr("JSON::{\"requestHeaders\": {\"x-trace\": \"trace-1\"}, \"body\": {\"wrapped\": $}, \"requestQuery\": {\"flag\": \"Y\"}} ");
|
||||
ApiStepDefinition stepDefinition = ApiStepDefinition.builder().step(stepDO).build();
|
||||
|
||||
ApiInvocationContext context = ApiInvocationContext.create();
|
||||
context.setRequestBody(Map.of("original", "value"));
|
||||
context.getRequestHeaders().put("tenant-id", "42");
|
||||
|
||||
GenericHandler<ApiInvocationContext> genericHandler = handler.build(aggregate, stepDefinition);
|
||||
ApiInvocationContext result = (ApiInvocationContext) genericHandler.handle(context, emptyHeaders());
|
||||
|
||||
assertThat(result).isSameAs(context);
|
||||
assertThat(result.getRequestHeaders()).containsEntry("x-trace", "trace-1");
|
||||
assertThat(result.getRequestQueryParams()).containsEntry("flag", "Y");
|
||||
assertThat(result.getRequestBody()).isInstanceOf(Map.class);
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, ?> mappedBody = (Map<String, ?>) result.getRequestBody();
|
||||
assertThat(mappedBody).containsKey("wrapped");
|
||||
assertThat(result.getStepResults()).hasSize(1);
|
||||
assertThat(result.getStepResults().get(0).isSuccess()).isTrue();
|
||||
assertThat(result.getStepResults().get(0).getStepId()).isEqualTo(101L);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRecordFailureWhenExpressionInvalid() {
|
||||
ApiStepDO stepDO = new ApiStepDO();
|
||||
stepDO.setId(202L);
|
||||
stepDO.setType("START");
|
||||
stepDO.setRequestMappingExpr("JSON::{invalid}");
|
||||
ApiStepDefinition stepDefinition = ApiStepDefinition.builder().step(stepDO).build();
|
||||
|
||||
ApiInvocationContext context = ApiInvocationContext.create();
|
||||
GenericHandler<ApiInvocationContext> genericHandler = handler.build(aggregate, stepDefinition);
|
||||
|
||||
assertThatThrownBy(() -> {
|
||||
genericHandler.handle(context, emptyHeaders());
|
||||
})
|
||||
.isInstanceOf(ServiceException.class)
|
||||
.extracting(ex -> ((ServiceException) ex).getCode())
|
||||
.isEqualTo(API_STEP_START_EXECUTION_FAILED.getCode());
|
||||
assertThat(context.getStepResults()).hasSize(1);
|
||||
assertThat(context.getStepResults().get(0).isSuccess()).isFalse();
|
||||
assertThat(context.getStepResults().get(0).getStepId()).isEqualTo(202L);
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,6 @@
|
||||
DELETE FROM "databus_api_transform";
|
||||
DELETE FROM "databus_api_step";
|
||||
DELETE FROM "databus_api_definition";
|
||||
DELETE FROM "databus_policy_auth";
|
||||
DELETE FROM "databus_policy_rate_limit";
|
||||
DELETE FROM "databus_policy_audit";
|
||||
DELETE FROM "databus_api_flow_publish";
|
||||
|
||||
@@ -1,18 +1,14 @@
|
||||
CREATE TABLE IF NOT EXISTS databus_api_definition (
|
||||
id BIGINT PRIMARY KEY,
|
||||
api_code VARCHAR(255) NOT NULL,
|
||||
uri_pattern VARCHAR(512),
|
||||
http_method VARCHAR(16),
|
||||
version VARCHAR(64),
|
||||
status INT,
|
||||
description VARCHAR(1024),
|
||||
auth_policy_id BIGINT,
|
||||
rate_limit_id BIGINT,
|
||||
audit_policy_id BIGINT,
|
||||
response_template CLOB,
|
||||
cache_strategy VARCHAR(255),
|
||||
updated_at TIMESTAMP,
|
||||
grey_released BOOLEAN,
|
||||
tenant_id BIGINT,
|
||||
create_time TIMESTAMP,
|
||||
update_time TIMESTAMP,
|
||||
@@ -32,7 +28,6 @@ CREATE TABLE IF NOT EXISTS databus_api_step (
|
||||
response_mapping_expr VARCHAR(1024),
|
||||
transform_id BIGINT,
|
||||
timeout BIGINT,
|
||||
retry_strategy VARCHAR(255),
|
||||
fallback_strategy VARCHAR(255),
|
||||
condition_expr VARCHAR(1024),
|
||||
stop_on_error BOOLEAN,
|
||||
@@ -60,20 +55,6 @@ CREATE TABLE IF NOT EXISTS databus_api_transform (
|
||||
deleted BOOLEAN
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS databus_policy_auth (
|
||||
id BIGINT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(64),
|
||||
config CLOB,
|
||||
description VARCHAR(512),
|
||||
tenant_id BIGINT,
|
||||
create_time TIMESTAMP,
|
||||
update_time TIMESTAMP,
|
||||
creator VARCHAR(64),
|
||||
updater VARCHAR(64),
|
||||
deleted BOOLEAN
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS databus_policy_rate_limit (
|
||||
id BIGINT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
|
||||
Reference in New Issue
Block a user