diff --git a/.gitignore b/.gitignore index 2c0c98f873..cfbf0b31fa 100644 --- a/.gitignore +++ b/.gitignore @@ -38,7 +38,6 @@ qywx.json ### VS Code ### .vscode/ -**/src/test/ ### flattened .flattened-pom.xml diff --git a/backend/.gitignore b/backend/.gitignore index df8a7b93e6..5d81d691f5 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -27,7 +27,7 @@ yarn-error.log* src/main/resources/static src/main/resources/public -src/test/ + target .settings .project diff --git a/backend/app/src/main/resources/migration/3.0.0/ddl/V2__ddl.sql b/backend/app/src/main/resources/migration/3.0.0/ddl/V2__ddl.sql new file mode 100644 index 0000000000..34d9b06689 --- /dev/null +++ b/backend/app/src/main/resources/migration/3.0.0/ddl/V2__ddl.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS `project` +( + `id` VARCHAR(50) NOT NULL COMMENT '项目ID', + `workspace_id` VARCHAR(50) NOT NULL COMMENT '工作空间ID', + `name` VARCHAR(64) NOT NULL COMMENT '项目名称', + `description` VARCHAR(255) COMMENT '项目描述', + `create_time` BIGINT NOT NULL COMMENT '创建时间', + `update_time` BIGINT NOT NULL COMMENT '更新时间', + `create_user` VARCHAR(100) COMMENT '创建人', + `system_id` VARCHAR(50) COMMENT '', + PRIMARY KEY (id) +) COMMENT = '项目'; diff --git a/backend/services/issue-management/pom.xml b/backend/services/issue-management/pom.xml new file mode 100644 index 0000000000..405e98c29c --- /dev/null +++ b/backend/services/issue-management/pom.xml @@ -0,0 +1,26 @@ + + + 4.0.0 + + io.metersphere + services + ${revision} + + metersphere-issue-management + ${revision} + issue-management + + + + + io.metersphere + metersphere-sdk + ${revision} + + + + + + + diff --git a/backend/services/issue-management/src/main/java/io/metersphere/issue/domain/TestCase.java b/backend/services/issue-management/src/main/java/io/metersphere/issue/domain/TestCase.java new file mode 100644 index 0000000000..3ab5d7c0a5 --- /dev/null +++ b/backend/services/issue-management/src/main/java/io/metersphere/issue/domain/TestCase.java @@ -0,0 +1,72 @@ +package io.metersphere.track.domain; + +import lombok.Data; + +import java.io.Serializable; + +@Data +public class TestCase implements Serializable { + private String id; + + private String nodeId; + + private String testId; + + private String nodePath; + + private String projectId; + + private String name; + + private String type; + + private String maintainer; + + private String priority; + + private String method; + + private Long createTime; + + private Long updateTime; + + private Integer sort; + + private Integer num; + + private String reviewStatus; + + private String tags; + + private String demandId; + + private String demandName; + + private String status; + + private String stepModel; + + private String customNum; + + private String createUser; + + private String originalStatus; + + private Long deleteTime; + + private String deleteUserId; + + private Long order; + + private Boolean casePublic; + + private String versionId; + + private String refId; + + private Boolean latest; + + private String lastExecuteResult; + + private static final long serialVersionUID = 1L; +} \ No newline at end of file diff --git a/backend/services/issue-management/src/main/java/io/metersphere/issue/util/TrackLogUtils.java b/backend/services/issue-management/src/main/java/io/metersphere/issue/util/TrackLogUtils.java new file mode 100644 index 0000000000..33a8e8dc6f --- /dev/null +++ b/backend/services/issue-management/src/main/java/io/metersphere/issue/util/TrackLogUtils.java @@ -0,0 +1,93 @@ +package io.metersphere.track.util; + +import io.metersphere.sdk.util.LogUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class TrackLogUtils extends LogUtils { + + /** + * 初始化日志 + * + * @return + */ + public static Logger getLogger() { + return LoggerFactory.getLogger("test-track"); + } + + public static void writeLog(Object msg, String level) { + writeLog(msg, level, getLogger()); + } + + public static void info(Object msg) { + info(msg, getLogger()); + } + + public static void info(Object msg, Object o1) { + info(msg, o1, getLogger().atError()); + } + + public static void info(Object msg, Object o1, Object o2) { + info(msg, o1, o2, getLogger()); + } + + public static void info(Object msg, Object[] obj) { + info(msg, obj, getLogger()); + } + + public static void debug(Object msg) { + debug(msg, getLogger()); + } + + public static void debug(Object msg, Object o) { + debug(msg, o, getLogger()); + } + + public static void debug(Object msg, Object o1, Object o2) { + debug(msg, o1, o2, getLogger()); + } + + public static void debug(Object msg, Object[] obj) { + debug(msg, obj, getLogger()); + } + + public static void warn(Object msg) { + warn(msg, getLogger()); + } + + public static void warn(Object msg, Object o) { + warn(msg, o, getLogger()); + } + + public static void warn(Object msg, Object o1, Object o2) { + warn(msg, o1, o2, getLogger()); + } + + public static void warn(Object msg, Object[] obj) { + warn(msg, obj, getLogger()); + } + + public static void error(Object msg) { + error(msg, getLogger()); + } + + public static void error(Throwable e) { + error(e, getLogger()); + } + + public static void error(Object msg, Object o) { + error(msg, o, getLogger()); + } + + public static void error(Object msg, Object o1, Object o2) { + error(msg, o1, o2, getLogger()); + } + + public static void error(Object msg, Object[] obj) { + error(msg, obj, getLogger()); + } + + public static void error(Object msg, Throwable ex) { + error(msg, ex, getLogger()); + } +} diff --git a/backend/services/issue-management/src/main/resources/i18n/issue.properties b/backend/services/issue-management/src/main/resources/i18n/issue.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/services/issue-management/src/main/resources/i18n/issue_en_US.properties b/backend/services/issue-management/src/main/resources/i18n/issue_en_US.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/services/issue-management/src/main/resources/i18n/issue_zh_CN.properties b/backend/services/issue-management/src/main/resources/i18n/issue_zh_CN.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/services/issue-management/src/main/resources/i18n/issue_zh_TW.properties b/backend/services/issue-management/src/main/resources/i18n/issue_zh_TW.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/backend/services/load-test/src/main/java/io/metersphere/load/domain/LoadTest.java b/backend/services/load-test/src/main/java/io/metersphere/load/domain/LoadTest.java index 209aba0931..f949f64959 100644 --- a/backend/services/load-test/src/main/java/io/metersphere/load/domain/LoadTest.java +++ b/backend/services/load-test/src/main/java/io/metersphere/load/domain/LoadTest.java @@ -22,17 +22,11 @@ public class LoadTest implements Serializable { private String testResourcePoolId; - private String userId; - private Integer num; private String createUser; - private Integer scenarioVersion; - - private String scenarioId; - - private Long order; + private Long pos; private String versionId; diff --git a/backend/services/pom.xml b/backend/services/pom.xml index cea307cb79..01ad486042 100644 --- a/backend/services/pom.xml +++ b/backend/services/pom.xml @@ -15,6 +15,7 @@ api-test + issue-management load-test project-management system-setting diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectController.java b/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectController.java new file mode 100644 index 0000000000..9baebee4d0 --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/controller/ProjectController.java @@ -0,0 +1,22 @@ +package io.metersphere.project.controller; + +import io.metersphere.project.domain.Project; +import io.metersphere.project.service.ProjectService; +import jakarta.annotation.Resource; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("project") +public class ProjectController { + @Resource + private ProjectService projectService; + + @GetMapping("list-all") + public List selectAll() { + return projectService.list(); + } +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/domain/Project.java b/backend/services/project-management/src/main/java/io/metersphere/project/domain/Project.java index 95dbcd52cf..bfc9c54224 100644 --- a/backend/services/project-management/src/main/java/io/metersphere/project/domain/Project.java +++ b/backend/services/project-management/src/main/java/io/metersphere/project/domain/Project.java @@ -18,33 +18,7 @@ public class Project implements Serializable { private Long updateTime; - private String tapdId; - - private String jiraKey; - - private String zentaoId; - - private String azureDevopsId; - - private String caseTemplateId; - - private String issueTemplateId; - - private String createUser; - private String systemId; - private String azureFilterId; - - private String platform; - - private Boolean thirdPartTemplate; - - private Boolean versionEnable; - - private String issueConfig; - - private String apiTemplateId; - private static final long serialVersionUID = 1L; } \ No newline at end of file diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ProjectMapper.java b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ProjectMapper.java new file mode 100644 index 0000000000..61c490c9ae --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/mapper/ProjectMapper.java @@ -0,0 +1,7 @@ +package io.metersphere.project.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import io.metersphere.project.domain.Project; + +public interface ProjectMapper extends BaseMapper { +} diff --git a/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java b/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java new file mode 100644 index 0000000000..e61de515ba --- /dev/null +++ b/backend/services/project-management/src/main/java/io/metersphere/project/service/ProjectService.java @@ -0,0 +1,13 @@ +package io.metersphere.project.service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import io.metersphere.project.domain.Project; +import io.metersphere.project.mapper.ProjectMapper; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(rollbackFor = Exception.class) +public class ProjectService extends ServiceImpl { + +} diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/Application.java b/backend/services/project-management/src/test/java/io/metersphere/project/Application.java new file mode 100644 index 0000000000..0432f9ae3a --- /dev/null +++ b/backend/services/project-management/src/test/java/io/metersphere/project/Application.java @@ -0,0 +1,23 @@ +package io.metersphere.project; + +import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration; +import org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration; +import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration; +import org.springframework.boot.web.servlet.ServletComponentScan; + +@SpringBootApplication(exclude = { + QuartzAutoConfiguration.class, + LdapAutoConfiguration.class, + Neo4jAutoConfiguration.class, + MybatisAutoConfiguration.class +}) +@ServletComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/config/MybatisConfig.java b/backend/services/project-management/src/test/java/io/metersphere/project/config/MybatisConfig.java new file mode 100644 index 0000000000..d340efa07e --- /dev/null +++ b/backend/services/project-management/src/test/java/io/metersphere/project/config/MybatisConfig.java @@ -0,0 +1,82 @@ +package io.metersphere.project.config; + +import com.fit2cloud.quartz.anno.QuartzDataSource; +import com.github.pagehelper.PageInterceptor; +import com.zaxxer.hikari.HikariDataSource; +import io.metersphere.sdk.interceptor.MybatisInterceptor; +import io.metersphere.sdk.interceptor.UserDesensitizationInterceptor; +import io.metersphere.sdk.util.MybatisInterceptorConfig; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.transaction.annotation.EnableTransactionManagement; + +import javax.sql.DataSource; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +@Configuration +@MapperScan(basePackages = {"io.metersphere.*.mapper"}, sqlSessionFactoryRef = "sqlSessionFactory") +@EnableTransactionManagement +public class MybatisConfig { + @Bean + @ConditionalOnMissingBean + public PageInterceptor pageInterceptor() { + PageInterceptor pageInterceptor = new PageInterceptor(); + Properties properties = new Properties(); + properties.setProperty("helperDialect", "mysql"); + properties.setProperty("rowBoundsWithCount", "true"); + properties.setProperty("reasonable", "true"); + properties.setProperty("offsetAsPageNum", "true"); + properties.setProperty("pageSizeZero", "true"); + pageInterceptor.setProperties(properties); + return pageInterceptor; + } + + @Bean + @ConditionalOnMissingBean + public MybatisInterceptor dbInterceptor() { + MybatisInterceptor interceptor = new MybatisInterceptor(); + List configList = new ArrayList<>(); +// configList.add(new MybatisInterceptorConfig(FileContent.class, "file", CompressUtils.class, "zip", "unzip")); + interceptor.setInterceptorConfigList(configList); + return interceptor; + } + + @Bean + public UserDesensitizationInterceptor userDesensitizationInterceptor() { + return new UserDesensitizationInterceptor(); + } + + + @Bean + @Primary + @ConfigurationProperties(prefix = "spring.datasource.hikari") + public DataSource dataSource(DataSourceProperties properties) { + return DataSourceBuilder.create(properties.getClassLoader()).type(HikariDataSource.class) + .driverClassName(properties.determineDriverClassName()) + .url(properties.determineUrl()) + .username(properties.determineUsername()) + .password(properties.determinePassword()) + .build(); + } + + @Bean + @ConfigurationProperties(prefix = "spring.datasource.quartz.hikari") + @QuartzDataSource + public DataSource quartzDataSource(DataSourceProperties properties) { + return DataSourceBuilder.create(properties.getClassLoader()).type(HikariDataSource.class) + .driverClassName(properties.determineDriverClassName()) + .url(properties.determineUrl()) + .username(properties.determineUsername()) + .password(properties.determinePassword()) + .build(); + } + +} diff --git a/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java new file mode 100644 index 0000000000..d2f86440f3 --- /dev/null +++ b/backend/services/project-management/src/test/java/io/metersphere/project/controller/ProjectControllerTests.java @@ -0,0 +1,31 @@ +package io.metersphere.project.controller; + +import jakarta.annotation.Resource; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; + +import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +@SpringBootTest +@AutoConfigureMockMvc +public class ProjectControllerTests { + @Resource + private MockMvc mockMvc; + + @Test + public void testSelectAll() throws Exception { + + mockMvc.perform(MockMvcRequestBuilders.get("/project/list-all")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) +// .andExpect(jsonPath("$.person.name").value("Jason")) + .andDo(print()); + } +} diff --git a/backend/services/project-management/src/test/resources/application.properties b/backend/services/project-management/src/test/resources/application.properties new file mode 100644 index 0000000000..14120a7a41 --- /dev/null +++ b/backend/services/project-management/src/test/resources/application.properties @@ -0,0 +1,76 @@ +spring.application.name=metersphere +management.server.port=7071 +server.port=8081 +# ?? gzip ?? +server.compression.enabled=true +server.compression.mime-types=application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css,text/javascript,image/jpeg +server.compression.min-response-size=2048 +# +quartz.enabled=false +quartz.scheduler-name=msScheduler +quartz.thread-count=10 +quartz.properties.org.quartz.jobStore.acquireTriggersWithinLock=true +# +logging.file.path=/opt/metersphere/logs/metersphere +# Hikari +spring.datasource.url=jdbc:mysql://localhost:${embedded.mysql.port}/test?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8 +spring.datasource.username=${embedded.mysql.user} +spring.datasource.password=${embedded.mysql.password} +spring.datasource.type=com.zaxxer.hikari.HikariDataSource +spring.datasource.hikari.maximum-pool-size=100 +spring.datasource.hikari.minimum-idle=10 +spring.datasource.hikari.idle-timeout=300000 +spring.datasource.hikari.auto-commit=true +spring.datasource.hikari.pool-name=DatebookHikariCP +spring.datasource.hikari.max-lifetime=1800000 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.connection-test-query=SELECT 1 + +# +# spring.kafka +spring.kafka.bootstrap-servers=${kafka.bootstrap-servers} +spring.kafka.consumer.group-id=metersphere_group_id +spring.kafka.consumer.debug.group-id=metersphere_group_id_${random.uuid} +spring.kafka.listener.missing-topics-fatal=false +spring.kafka.producer.properties.max.request.size=32428800 +spring.kafka.producer.batch-size=16384 +spring.kafka.consumer.properties.max.partition.fetch.bytes=52428800 +# mybatis +mybatis.configuration.cache-enabled=true +mybatis.configuration.lazy-loading-enabled=false +mybatis.configuration.aggressive-lazy-loading=true +mybatis.configuration.multiple-result-sets-enabled=true +mybatis.configuration.use-column-label=true +mybatis.configuration.auto-mapping-behavior=full +mybatis.configuration.default-statement-timeout=25000 +mybatis.configuration.map-underscore-to-camel-case=true +# view +spring.mvc.throw-exception-if-no-handler-found=true +# flyway enable +spring.flyway.enabled=true +spring.flyway.baseline-on-migrate=true +spring.flyway.locations=filesystem:../../app/src/main/resources/migration +spring.flyway.table=metersphere_version +spring.flyway.baseline-version=0 +spring.flyway.encoding=UTF-8 +spring.flyway.validate-on-migrate=false +# jmeter +jmeter.home=/opt/jmeter +# file upload +spring.servlet.multipart.max-file-size=500MB +spring.servlet.multipart.max-request-size=500MB +# i18n +spring.messages.basename=i18n/messages,i18n/api,i18n/load,i18n/project,i18n/system,i18n/plan,i18n/track,i18n/ui,i18n/workstation +# actuator +management.endpoints.web.exposure.include=* +management.endpoints.enabled-by-default=false +# redis +spring.session.timeout=43200s +spring.data.redis.host=localhost +spring.data.redis.password=${embedded.redis.password} +spring.data.redis.port=${embedded.redis.port} +spring.session.redis.repository-type=indexed +# +spring.freemarker.check-template-location=false +spring.groovy.template.check-template-location=false +# diff --git a/backend/services/project-management/src/test/resources/bootstrap.properties b/backend/services/project-management/src/test/resources/bootstrap.properties new file mode 100644 index 0000000000..38cc3b010b --- /dev/null +++ b/backend/services/project-management/src/test/resources/bootstrap.properties @@ -0,0 +1,9 @@ +# embedded config +embedded.containers.enabled=true +embedded.containers.forceShutdown=true +# mysql +embedded.mysql.enabled=true +embedded.mysql.encoding=utf8mb4 +embedded.mysql.collation=utf8mb4_general_ci +# redis +embedded.redis.enabled=true \ No newline at end of file diff --git a/pom.xml b/pom.xml index 18a518388d..82fc3b578f 100644 --- a/pom.xml +++ b/pom.xml @@ -85,6 +85,7 @@ 6.5.0.202303070854-r 5.4.0 22.3.1 + 2.3.2 1.12.1 v16.10.0 @@ -121,6 +122,39 @@ + + + org.springframework.cloud + spring-cloud-starter-bootstrap + 4.0.2 + test + + + com.playtika.testcontainers + embedded-mysql + ${embedded.version} + test + + + com.playtika.testcontainers + embedded-redis + ${embedded.version} + test + + + +