diff --git a/carp-dependencies/pom.xml b/carp-dependencies/pom.xml new file mode 100644 index 00000000..0559d4fa --- /dev/null +++ b/carp-dependencies/pom.xml @@ -0,0 +1,706 @@ + + + + + 4.0.0 + cn.sliew + carp-dependencies + 0.0.13-SNAPSHOT + pom + + carp-dependencies + Carp Dependencies + https://github.com/flowerfine/carp + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + git@github.com:flowerfine/carp.git + scm:git:git@github.com:flowerfine/carp.git + https://github.com/flowerfine/carp + HEAD + + + + + kalencaya + 1942460489@qq.com + + + + + Github Issue + https://github.com/flowerfine/carp/issues + + + + + sonatype-nexus + Sonatype Nexus Snapshots + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus + Sonatype Nexus Release + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + 2023.0.1 + 3.3.0 + 0.1.1 + 1.4.2.Final + 0.2.0 + 1.18.32 + 5.8.30 + 3.12.0 + 1.9.4 + 1.9 + 1.19 + 2.11.0 + 33.2.1-jre + 1.0.13 + + 3.0.3 + 3.5.7 + 2.2 + 8.3.0 + 42.3.3 + 2.3.230 + + 1.38.0 + 4.5.0 + 3.3.4 + 1.1.0-M1 + 8.3.8 + 3.27.2 + 4.3.2 + 1.5.2 + 0.4.14 + 0.9.0 + 1.1.1 + 3.9.0 + 3.12.1 + 0.9.0 + 6.9.2 + 7.6.1 + 0.5.1 + 3.3.2 + 0.0.9 + 9.7 + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring.cloud.version} + pom + import + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + com.github.xiaoymin + knife4j-dependencies + ${knife4j.version} + pom + import + + + org.zalando + logbook-bom + ${logbook.version} + pom + import + + + + ${project.groupId} + carp-framework-common + ${project.version} + + + ${project.groupId} + carp-framework-dag + ${project.version} + + + ${project.groupId} + carp-framework-exception + ${project.version} + + + ${project.groupId} + carp-framework-metrics + ${project.version} + + + ${project.groupId} + carp-framework-mongo + ${project.version} + + + ${project.groupId} + carp-framework-mybatis + ${project.version} + + + ${project.groupId} + carp-framework-pekko + ${project.version} + + + ${project.groupId} + carp-framework-redis + ${project.version} + + + ${project.groupId} + carp-framework-spring + ${project.version} + + + ${project.groupId} + carp-framework-web + ${project.version} + + + + ${project.groupId} + carp-module-alert + ${project.version} + + + ${project.groupId} + carp-module-application-vela + ${project.version} + + + ${project.groupId} + carp-module-datasource + ${project.version} + + + ${project.groupId} + carp-module-http-framework + ${project.version} + + + ${project.groupId} + carp-module-kubernetes + ${project.version} + + + ${project.groupId} + carp-module-plugin + ${project.version} + + + ${project.groupId} + carp-module-scheduler-base + ${project.version} + + + ${project.groupId} + carp-module-scheduler-quartz + ${project.version} + + + ${project.groupId} + carp-module-queue-api + ${project.version} + + + ${project.groupId} + carp-module-security-core + ${project.version} + + + ${project.groupId} + carp-module-security-spring + ${project.version} + + + ${project.groupId} + carp-module-system + ${project.version} + + + ${project.groupId} + carp-module-workflow-api + ${project.version} + + + ${project.groupId} + carp-module-workflow-internal + ${project.version} + + + + ${project.groupId} + carp-plugin-schedule-api + ${project.version} + + + ${project.groupId} + carp-plugin-test-api + ${project.version} + + + + ${project.groupId} + carp-server + ${project.version} + + + + org.projectlombok + lombok + ${org.projectlombok.version} + + + + org.mapstruct.extensions.spring + mapstruct-spring-annotations + ${org.mapstruct.extensions.spring.version} + + + org.mapstruct + mapstruct + ${org.mapstruct.version} + + + + cn.hutool + hutool-all + ${hutool.version} + + + org.apache.commons + commons-lang3 + ${commons.lang3.version} + + + commons-beanutils + commons-beanutils + ${commons.beanutils.version} + + + org.apache.commons + commons-text + ${commons.text.version} + + + org.apache.commons + commons-compress + ${commons.compress.version} + + + commons-io + commons-io + ${commons.io.version} + + + + com.google.guava + guava + ${guava.version} + + + + cn.sliew + milky-common + ${milky.version} + + + cn.sliew + milky-registry + ${milky.version} + + + cn.sliew + milky-test + ${milky.version} + + + + + org.mybatis + mybatis-spring + ${mybatis.spring.version} + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis.plus.version} + + + org.mybatis + mybatis-spring + + + + + com.baomidou + mybatis-plus-core + ${mybatis.plus.version} + + + com.baomidou + mybatis-plus-generator + ${mybatis.plus.version} + + + org.apache.velocity + velocity-engine-core + ${velocity.engine.version} + + + + com.mysql + mysql-connector-j + runtime + ${mysql.version} + + + org.postgresql + postgresql + runtime + ${postgresql.version} + + + com.h2database + h2 + ${h2.version} + + + + + cn.dev33 + sa-token-spring-boot-starter + ${sa-token.version} + + + + org.apache.hadoop + hadoop-common + ${hadoop.version} + + + org.slf4j + slf4j-api + + + org.slf4j + slf4j-reload4j + + + org.slf4j + slf4j-log4j12 + + + commons-logging + commons-logging + + + ch.qos.reload4j + reload4j + + + javax.servlet + javax.servlet-api + + + javax.servlet.jsp + jsp-api + + + + + org.apache.hadoop + hadoop-hdfs-client + ${hadoop.version} + + + org.apache.hadoop + hadoop-hdfs + ${hadoop.version} + + + org.apache.hadoop + hadoop-aliyun + ${hadoop.version} + + + org.apache.hadoop + hadoop-aws + ${hadoop.version} + + + + org.apache.pekko + pekko-actor-typed_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-cluster-typed_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-cluster-sharding-typed_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-stream_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-serialization-jackson_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-persistence-typed_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-persistence-jdbc_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-http_${scala.binary.version} + ${pekko.version} + + + org.apache.pekko + pekko-http-jackson_${scala.binary.version} + ${pekko.version} + + + + io.minio + minio + ${minio.version} + + + + org.redisson + redisson-spring-boot-starter + ${redisson.version} + + + + com.alibaba.cola + cola-component-statemachine + ${cola.version} + + + + org.furyio + fury-core + ${fury.version} + + + + org.jgrapht + jgrapht-core + ${jgrapht.version} + + + + com.github.zafarkhaja + java-semver + ${semver.version} + + + + com.flipkart.zjsonpatch + zjsonpatch + ${zjsonpatch.version} + + + + com.google.auto.service + auto-service + ${auto-service.version} + + + + org.pf4j + pf4j + ${pf4j.version} + + + org.pf4j + pf4j-spring + ${pf4j.version} + + + + io.fabric8 + kubernetes-client + ${kubernetes-client.version} + + + + org.javers + javers-spring-boot-starter-sql + ${javers.version} + + + org.javers + javers-spring + ${javers.version} + + + + com.alibaba + easyexcel + ${easyexcel.version} + + + + com.tencent.devops + devops-boot-starter-schedule-server + ${bkdevops.version} + + + + org.ow2.asm + asm + ${asm.version} + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.7.0 + true + + sonatype-nexus + https://s01.oss.sonatype.org/ + true + + + + + + + + oss-release + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + verify + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + + sign + + + + + + + --pinentry-mode + loopback + + + + + + org.apache.maven.plugins + maven-remote-resources-plugin + + + process-resource-bundles + + process + + + + org.apache:apache-jar-resource-bundle:1.4 + + + + + + + + + + + \ No newline at end of file diff --git a/carp-dist/pom.xml b/carp-dist/pom.xml index ca9ab337..8856418b 100644 --- a/carp-dist/pom.xml +++ b/carp-dist/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT carp-dist diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/pom.xml b/carp-examples/carp-ageiport-example/carp-ageiport-processor/pom.xml index ae9ce88e..413de834 100644 --- a/carp-examples/carp-ageiport-example/carp-ageiport-processor/pom.xml +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-ageiport-example - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-ageiport-processor @@ -43,6 +43,11 @@ ageiport-processor-core + + net.datafaker + datafaker + + org.junit.jupiter junit-jupiter diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/example/ageiport/controller/EasyExcelController.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/example/ageiport/controller/EasyExcelController.java new file mode 100644 index 00000000..3ced556a --- /dev/null +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/example/ageiport/controller/EasyExcelController.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.example.ageiport.controller; + +import cn.hutool.core.io.FileUtil; +import cn.hutool.core.lang.UUID; +import cn.sliew.carp.example.ageiport.util.DataFakerUtil; +import cn.sliew.carp.processor.core.model.UserData; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelWriter; +import com.alibaba.excel.write.metadata.WriteSheet; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.io.File; + +@RestController +@RequestMapping("/api/carp/example/ageiport/easyexcel") +@Tag(name = "测试模块-EasyExcel功能") +public class EasyExcelController { + + @GetMapping + @Operation(summary = "测试流式导出", description = "测试流式导出") + public void testStreamExport() throws Exception { + File file = FileUtil.file(FileUtil.getUserHomePath() + "/Downloads/export/" + UUID.fastUUID().toString(true) + ".xlsx"); + if (FileUtil.exist(file) == false) { + file.createNewFile(); + } + +// EasyExcel.write(file).head(UserData.class).sheet(1).doWrite(DataFakerUtil.generateList(5)); + // 这种指定 sheet 的方式必须执行 finish() 方法。上面的 doWrite() 方法内部会自己执行 finish() 方法 + try (ExcelWriter excelWriter = EasyExcel.write(file).head(UserData.class).inMemory(false).autoCloseStream(true).build()) { + // excel 单个 sheet 最多可写入 1048576 条数据。超出后需重新写 + for (int i = 1 ; i <= 10; i++) { + WriteSheet writeSheet = EasyExcel.writerSheet(i, "测试" + i).head(UserData.class).build(); + doWriteSheet(excelWriter, writeSheet); + System.out.println(String.format("写入第%d批次数据", i)); + } + } + } + + private void doWriteSheet(ExcelWriter excelWriter, WriteSheet writeSheet) { + for (int i = 0; i < 50; i++) { + excelWriter.write(DataFakerUtil.generateList(10000), writeSheet); + } + } + +} diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/example/ageiport/util/DataFakerUtil.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/example/ageiport/util/DataFakerUtil.java new file mode 100644 index 00000000..b6810de0 --- /dev/null +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/example/ageiport/util/DataFakerUtil.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.example.ageiport.util; + +import cn.sliew.carp.processor.core.model.UserData; +import net.datafaker.Faker; +import net.datafaker.transformations.Field; +import net.datafaker.transformations.JavaObjectTransformer; +import net.datafaker.transformations.Schema; + +import java.math.BigDecimal; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +public enum DataFakerUtil { + ; + + private static final Faker FAKER = new Faker(); + private static final JavaObjectTransformer J_TRANSFORMER = new JavaObjectTransformer(); + + public static Schema userDataSchema() { + return Schema.of( + Field.field("id", () -> FAKER.number().positive()), + Field.field("name", () -> FAKER.name().fullName()), + Field.field("gender", () -> FAKER.gender().types()), + Field.field("age", () -> BigDecimal.valueOf(FAKER.number().numberBetween(1, 100))), + Field.field("groupIndex", () -> FAKER.number().numberBetween(1, 3)), + + Field.field("manQuestion1", () -> FAKER.name().fullName()), + Field.field("manQuestion2", () -> FAKER.name().fullName()), + Field.field("womenQuestion1", () -> FAKER.name().fullName()), + Field.field("womenQuestion2", () -> FAKER.name().fullName()), + Field.field("otherQuestion1", () -> FAKER.name().fullName()), + Field.field("otherQuestion2", () -> FAKER.name().fullName()) + ); + } + + public static UserData generate() { + return (UserData) J_TRANSFORMER.apply(UserData.class, userDataSchema()); + } + + public static List generateList(Integer count) { + return IntStream.range(0, count).mapToObj(index -> generate()).collect(Collectors.toList()); + } +} diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/BaseExportProcessor.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/BaseExportProcessor.java new file mode 100644 index 00000000..1983c5c4 --- /dev/null +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/BaseExportProcessor.java @@ -0,0 +1,62 @@ +package cn.sliew.carp.processor.core.exporter; + +import cn.sliew.carp.processor.core.model.UserData; +import cn.sliew.carp.processor.core.model.UserQuery; +import cn.sliew.carp.processor.core.model.UserView; +import com.alibaba.ageiport.common.utils.BeanUtils; +import com.alibaba.ageiport.processor.core.exception.BizException; +import com.alibaba.ageiport.processor.core.model.api.BizExportPage; +import com.alibaba.ageiport.processor.core.model.api.BizUser; +import com.alibaba.ageiport.processor.core.task.exporter.ExportProcessor; +import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfig; +import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfigImpl; + +import java.util.ArrayList; +import java.util.List; + +public class BaseExportProcessor implements ExportProcessor { + + @Override + public Integer totalCount(BizUser bizUser, UserQuery query) throws BizException { + return query.getTotalCount(); + } + + @Override + public List queryData(BizUser user, UserQuery query, BizExportPage bizExportPage) throws BizException { + List dataList = new ArrayList<>(); + + Integer totalCount = query.getTotalCount(); + for (int i = 1; i <= totalCount; i++) { + final UserData data = new UserData(); + data.setId(i); + data.setName("name" + i); + if (i % 3 == 0) { + data.setGender("男"); + } + if (i % 3 == 1) { + data.setGender("女"); + } + if (i % 3 == 2) { + data.setGender("其他"); + } + dataList.add(data); + } + return dataList; + } + + @Override + public List convert(BizUser user, UserQuery query, List data) throws BizException { + List dataList = new ArrayList<>(); + for (UserData datum : data) { + UserView view = BeanUtils.cloneProp(datum, UserView.class); + dataList.add(view); + } + return dataList; + } + + public BizExportTaskRuntimeConfig taskRuntimeConfig(BizUser user, UserQuery query) throws BizException { + final BizExportTaskRuntimeConfigImpl runtimeConfig = new BizExportTaskRuntimeConfigImpl(); + runtimeConfig.setExecuteType("STANDALONE"); + return runtimeConfig; + } +} diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/CSVExportProcessor.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/CSVExportProcessor.java index 45fdf649..a565c8ef 100644 --- a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/CSVExportProcessor.java +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/CSVExportProcessor.java @@ -1,68 +1,16 @@ package cn.sliew.carp.processor.core.exporter; -import cn.sliew.carp.processor.core.model.UserData; import cn.sliew.carp.processor.core.model.UserQuery; -import cn.sliew.carp.processor.core.model.UserView; -import com.alibaba.ageiport.common.utils.BeanUtils; import com.alibaba.ageiport.processor.core.annotation.ExportSpecification; import com.alibaba.ageiport.processor.core.exception.BizException; -import com.alibaba.ageiport.processor.core.model.api.BizExportPage; import com.alibaba.ageiport.processor.core.model.api.BizUser; -import com.alibaba.ageiport.processor.core.task.exporter.ExportProcessor; import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfig; import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfigImpl; -import java.util.ArrayList; -import java.util.List; - - -//1.实现ExportProcessor接口 @ExportSpecification(code = "CSVExportProcessor", name = "CSVExportProcessor") -public class CSVExportProcessor implements ExportProcessor { - - //2.实现ExportProcessor接口的TotalCount方法 - @Override - public Integer totalCount(BizUser bizUser, UserQuery query) throws BizException { - return query.getTotalCount(); - } +public class CSVExportProcessor extends BaseExportProcessor { - //3.实现ExportProcessor接口的queryData方法 @Override - public List queryData(BizUser user, UserQuery query, BizExportPage bizExportPage) throws BizException { - List dataList = new ArrayList<>(); - - Integer offset = bizExportPage.getOffset(); - Integer size = bizExportPage.getSize(); - for (int i = 1; i <= size; i++) { - int index = offset + i; - final UserData data = new UserData(); - data.setId(index); - data.setName("name" + index); - if (index % 3 == 0) { - data.setGender("男"); - } - if (index % 3 == 1) { - data.setGender("女"); - } - if (index % 3 == 2) { - data.setGender("其他"); - } - dataList.add(data); - } - return dataList; - } - - //4.实现ExportProcessor接口的convert方法 - @Override - public List convert(BizUser user, UserQuery query, List data) throws BizException { - List dataList = new ArrayList<>(); - for (UserData datum : data) { - UserView view = BeanUtils.cloneProp(datum, UserView.class); - dataList.add(view); - } - return dataList; - } - public BizExportTaskRuntimeConfig taskRuntimeConfig(BizUser user, UserQuery query) throws BizException { final BizExportTaskRuntimeConfigImpl runtimeConfig = new BizExportTaskRuntimeConfigImpl(); runtimeConfig.setExecuteType("STANDALONE"); diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ClusterExportProcessor.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ClusterExportProcessor.java index 5f3ec850..8bbc76dc 100644 --- a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ClusterExportProcessor.java +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ClusterExportProcessor.java @@ -1,60 +1,15 @@ package cn.sliew.carp.processor.core.exporter; -import cn.sliew.carp.processor.core.model.UserData; import cn.sliew.carp.processor.core.model.UserQuery; -import cn.sliew.carp.processor.core.model.UserView; -import com.alibaba.ageiport.common.utils.BeanUtils; import com.alibaba.ageiport.processor.core.annotation.ExportSpecification; import com.alibaba.ageiport.processor.core.constants.ExecuteType; import com.alibaba.ageiport.processor.core.exception.BizException; -import com.alibaba.ageiport.processor.core.model.api.BizExportPage; import com.alibaba.ageiport.processor.core.model.api.BizUser; -import com.alibaba.ageiport.processor.core.task.exporter.ExportProcessor; import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfig; import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfigImpl; -import java.util.ArrayList; -import java.util.List; - @ExportSpecification(code = "ClusterExportProcessor", name = "ClusterExportProcessor", executeType = ExecuteType.CLUSTER) -public class ClusterExportProcessor implements ExportProcessor { - @Override - public Integer totalCount(BizUser bizUser, UserQuery query) throws BizException { - return query.getTotalCount(); - } - - @Override - public List queryData(BizUser user, UserQuery query, BizExportPage bizExportPage) throws BizException { - List dataList = new ArrayList<>(); - - Integer totalCount = query.getTotalCount(); - for (int i = 1; i <= totalCount; i++) { - final UserData data = new UserData(); - data.setId(i); - data.setName("name" + i); - if (i % 3 == 0) { - data.setGender("男"); - } - if (i % 3 == 1) { - data.setGender("女"); - } - if (i % 3 == 2) { - data.setGender("其他"); - } - dataList.add(data); - } - return dataList; - } - - @Override - public List convert(BizUser user, UserQuery query, List data) throws BizException { - List dataList = new ArrayList<>(); - for (UserData datum : data) { - UserView view = BeanUtils.cloneProp(datum, UserView.class); - dataList.add(view); - } - return dataList; - } +public class ClusterExportProcessor extends BaseExportProcessor { @Override public BizExportTaskRuntimeConfig taskRuntimeConfig(BizUser user, UserQuery query) throws BizException { diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ExcelStyleExportProcessor.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ExcelStyleExportProcessor.java index 4640f6fe..280a5931 100644 --- a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ExcelStyleExportProcessor.java +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/ExcelStyleExportProcessor.java @@ -1,69 +1,8 @@ package cn.sliew.carp.processor.core.exporter; -import cn.sliew.carp.processor.core.model.UserData; -import cn.sliew.carp.processor.core.model.UserQuery; -import cn.sliew.carp.processor.core.model.UserView; -import com.alibaba.ageiport.common.utils.BeanUtils; import com.alibaba.ageiport.processor.core.annotation.ExportSpecification; -import com.alibaba.ageiport.processor.core.exception.BizException; -import com.alibaba.ageiport.processor.core.model.api.BizExportPage; -import com.alibaba.ageiport.processor.core.model.api.BizUser; -import com.alibaba.ageiport.processor.core.task.exporter.ExportProcessor; -import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfig; -import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfigImpl; - -import java.util.ArrayList; -import java.util.List; @ExportSpecification(code = "ExcelStyleExportProcessor", name = "ExcelStyleExportProcessor") -public class ExcelStyleExportProcessor implements ExportProcessor { - - //2.实现ExportProcessor接口的TotalCount方法 - @Override - public Integer totalCount(BizUser bizUser, UserQuery query) throws BizException { - return query.getTotalCount(); - } - - //3.实现ExportProcessor接口的queryData方法 - @Override - public List queryData(BizUser user, UserQuery query, BizExportPage bizExportPage) throws BizException { - List dataList = new ArrayList<>(); - - Integer offset = bizExportPage.getOffset(); - Integer size = bizExportPage.getSize(); - for (int i = 1; i <= size; i++) { - int index = offset + i; - final UserData data = new UserData(); - data.setId(index); - data.setName("name" + index); - if (index % 3 == 0) { - data.setGender("男"); - } - if (index % 3 == 1) { - data.setGender("女"); - } - if (index % 3 == 2) { - data.setGender("其他"); - } - dataList.add(data); - } - return dataList; - } - - //4.实现ExportProcessor接口的convert方法 - @Override - public List convert(BizUser user, UserQuery query, List data) throws BizException { - List dataList = new ArrayList<>(); - for (UserData datum : data) { - UserView view = BeanUtils.cloneProp(datum, UserView.class); - dataList.add(view); - } - return dataList; - } +public class ExcelStyleExportProcessor extends BaseExportProcessor { - public BizExportTaskRuntimeConfig taskRuntimeConfig(BizUser user, UserQuery query) throws BizException { - final BizExportTaskRuntimeConfigImpl runtimeConfig = new BizExportTaskRuntimeConfigImpl(); - runtimeConfig.setExecuteType("STANDALONE"); - return runtimeConfig; - } } diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/StandaloneExportProcessor.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/StandaloneExportProcessor.java index 5117db81..07ca3e81 100644 --- a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/StandaloneExportProcessor.java +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/StandaloneExportProcessor.java @@ -1,73 +1,16 @@ package cn.sliew.carp.processor.core.exporter; -import cn.sliew.carp.processor.core.model.UserData; import cn.sliew.carp.processor.core.model.UserQuery; -import cn.sliew.carp.processor.core.model.UserView; -import com.alibaba.ageiport.common.utils.BeanUtils; import com.alibaba.ageiport.processor.core.annotation.ExportSpecification; import com.alibaba.ageiport.processor.core.exception.BizException; -import com.alibaba.ageiport.processor.core.model.api.BizExportPage; import com.alibaba.ageiport.processor.core.model.api.BizUser; -import com.alibaba.ageiport.processor.core.task.exporter.ExportProcessor; import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfig; import com.alibaba.ageiport.processor.core.task.exporter.api.BizExportTaskRuntimeConfigImpl; -import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; - -//1.实现ExportProcessor接口 @ExportSpecification(code = "StandaloneExportProcessor", name = "StandaloneExportProcessor") -public class StandaloneExportProcessor implements ExportProcessor { - - //2.实现ExportProcessor接口的TotalCount方法 - @Override - public Integer totalCount(BizUser bizUser, UserQuery query) throws BizException { - return query.getTotalCount(); - } +public class StandaloneExportProcessor extends BaseExportProcessor { - //3.实现ExportProcessor接口的queryData方法 @Override - public List queryData(BizUser user, UserQuery query, BizExportPage bizExportPage) throws BizException { - if (query.isErrorWhenQueryData()) { - throw new BizException("BIZ_EXC_001", "Error when query"); - } - - List dataList = new ArrayList<>(); - - Integer offset = bizExportPage.getOffset(); - Integer size = bizExportPage.getSize(); - for (int i = 1; i <= size; i++) { - int index = offset + i; - final UserData data = new UserData(); - data.setId(index); - data.setName("name" + index); - if (index % 3 == 0) { - data.setGender("男"); - } - if (index % 3 == 1) { - data.setGender("女"); - } - if (index % 3 == 2) { - data.setGender("其他"); - } - data.setAge(new BigDecimal(10)); - dataList.add(data); - } - return dataList; - } - - //4.实现ExportProcessor接口的convert方法 - @Override - public List convert(BizUser user, UserQuery query, List data) throws BizException { - List dataList = new ArrayList<>(); - for (UserData datum : data) { - UserView view = BeanUtils.cloneProp(datum, UserView.class); - dataList.add(view); - } - return dataList; - } - public BizExportTaskRuntimeConfig taskRuntimeConfig(BizUser user, UserQuery query) throws BizException { final BizExportTaskRuntimeConfigImpl runtimeConfig = new BizExportTaskRuntimeConfigImpl(); runtimeConfig.setExecuteType("STANDALONE"); diff --git a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/UdfSliceStrategyExportProcessor.java b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/UdfSliceStrategyExportProcessor.java index f8903997..a8ac98f8 100644 --- a/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/UdfSliceStrategyExportProcessor.java +++ b/carp-examples/carp-ageiport-example/carp-ageiport-processor/src/main/java/cn/sliew/carp/processor/core/exporter/UdfSliceStrategyExportProcessor.java @@ -20,32 +20,24 @@ import java.util.*; -//1.实现ExportProcessor接口 @ExportSpecification(code = "UdfSliceStrategyExportProcessor", name = "UdfSliceStrategyExportProcessor", sliceStrategy = "UdfExportSliceStrategy") -public class UdfSliceStrategyExportProcessor implements ExportProcessor { +public class UdfSliceStrategyExportProcessor extends BaseExportProcessor { - //2.实现ExportProcessor接口的TotalCount方法 - @Override - public Integer totalCount(BizUser bizUser, UserQuery query) throws BizException { - return query.getTotalCount(); - } - - //3.实现ExportProcessor接口的queryData方法 @Override public List queryData(BizUser user, UserQuery query, BizExportPage bizExportPage) throws BizException { List data = new ArrayList<>(); String sliceKey = query.getSliceKey(); if (Objects.equals(sliceKey, "男")) { - data = queryMan(user, query, bizExportPage); + data = doQueryData(user, query, bizExportPage, 0, "男"); } else if (Objects.equals(sliceKey, "女")) { - data = queryWomen(user, query, bizExportPage); + data = doQueryData(user, query, bizExportPage, 1, "女"); } else if (Objects.equals(sliceKey, "其他")) { - data = queryOthers(user, query, bizExportPage); + data = doQueryData(user, query, bizExportPage, 2, "其他"); } return data; } - private List queryOthers(BizUser user, UserQuery query, BizExportPage bizExportPage) { + private List doQueryData(BizUser user, UserQuery query, BizExportPage bizExportPage, Integer groupIndex, String gender) { List dataList = new ArrayList<>(); Integer offset = bizExportPage.getOffset(); Integer size = bizExportPage.getSize(); @@ -54,65 +46,18 @@ private List queryOthers(BizUser user, UserQuery query, BizExportPage final UserData data = new UserData(); data.setId(index); data.setName("name" + index); - data.setGender("其他"); - data.setGroupIndex(2); - data.setGroupName("其他性别问卷"); - data.setOtherQuestion1("其他性别问题回答1"); + data.setGender(gender); + data.setGroupIndex(groupIndex); + data.setGroupName(String.format("%s性别问卷", gender)); + data.setOtherQuestion1(String.format("%s性别问题回答1", gender)); + data.setOtherQuestion2(String.format("%s性别问题回答2", gender)); + data.setOtherQuestion2("其他性别问题回答2"); data.setOtherQuestion2("其他性别问题回答2"); dataList.add(data); } return dataList; } - private List queryWomen(BizUser user, UserQuery query, BizExportPage bizExportPage) { - List dataList = new ArrayList<>(); - Integer offset = bizExportPage.getOffset(); - Integer size = bizExportPage.getSize(); - for (int i = 1; i <= size; i++) { - int index = offset + i; - final UserData data = new UserData(); - data.setId(index); - data.setName("name" + index); - data.setGender("女"); - data.setGroupIndex(1); - data.setGroupName("女性性别问卷"); - data.setWomenQuestion1("女性性别问题回答1"); - data.setWomenQuestion2("女性性别问题回答2"); - dataList.add(data); - } - return dataList; - } - - private List queryMan(BizUser user, UserQuery query, BizExportPage bizExportPage) { - List dataList = new ArrayList<>(); - Integer offset = bizExportPage.getOffset(); - Integer size = bizExportPage.getSize(); - for (int i = 1; i <= size; i++) { - int index = offset + i; - final UserData data = new UserData(); - data.setId(index); - data.setName("name" + index); - data.setGender("男"); - data.setGroupIndex(0); - data.setGroupName("男性性别问卷"); - data.setManQuestion1("男性别问题回答1"); - data.setManQuestion2("男性别问题回答2"); - dataList.add(data); - } - return dataList; - } - - //4.实现ExportProcessor接口的convert方法 - @Override - public List convert(BizUser user, UserQuery query, List data) throws BizException { - List dataList = new ArrayList<>(); - for (UserData datum : data) { - UserView view = BeanUtils.cloneProp(datum, UserView.class); - dataList.add(view); - } - return dataList; - } - @Override public BizDataGroup group(BizUser user, UserQuery query, List views) { BizDataGroupImpl group = new BizDataGroupImpl<>(); @@ -133,15 +78,6 @@ public BizDataGroup group(BizUser user, UserQuery query, List cn.sliew carp-ageiport-example - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-ageiport-server diff --git a/carp-examples/carp-ageiport-example/pom.xml b/carp-examples/carp-ageiport-example/pom.xml index 69865507..cbea1db5 100644 --- a/carp-examples/carp-ageiport-example/pom.xml +++ b/carp-examples/carp-ageiport-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-ageiport-example @@ -38,6 +38,7 @@ true 0.3.2 3.3.2 + 2.4.0 5.9.0 @@ -62,6 +63,12 @@ ${ageiport.version} + + net.datafaker + datafaker + ${datafaker.version} + + org.junit.jupiter junit-jupiter diff --git a/carp-examples/carp-camellia-example/pom.xml b/carp-examples/carp-camellia-example/pom.xml index 7a5bf6f6..5a554a53 100644 --- a/carp-examples/carp-camellia-example/pom.xml +++ b/carp-examples/carp-camellia-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-camellia-example diff --git a/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/config/CamelliaConfig.java b/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/config/CamelliaConfig.java index ec6c3fdf..956b6151 100644 --- a/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/config/CamelliaConfig.java +++ b/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/config/CamelliaConfig.java @@ -22,7 +22,11 @@ import org.springframework.context.annotation.Configuration; @Configuration -@ComponentScan(basePackages = {"com.netease.nim.camellia.redis.springboot", - "com.netease.nim.camellia.delayqueue.server"}) +@ComponentScan(basePackages = { + "com.netease.nim.camellia.redis.springboot", + "com.netease.nim.camellia.delayqueue.server.springboot", + "com.netease.nim.camellia.delayqueue.sdk.springboot" +}) public class CamelliaConfig { + } diff --git a/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/controller/DelayMsgController.java b/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/controller/DelayMsgController.java index 028e0558..b683c386 100644 --- a/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/controller/DelayMsgController.java +++ b/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/controller/DelayMsgController.java @@ -18,9 +18,9 @@ package cn.sliew.carp.example.camellia.controller; -import cn.sliew.carp.example.camellia.listener.ConsumerService1; +import cn.sliew.carp.example.camellia.service.DelayMsgService; import com.netease.nim.camellia.delayqueue.common.domain.CamelliaDelayMsg; -import com.netease.nim.camellia.delayqueue.sdk.CamelliaDelayQueueSdk; +import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -29,8 +29,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.concurrent.TimeUnit; - @Slf4j @RestController @RequestMapping("/api/carp/example/camellia") @@ -38,15 +36,23 @@ public class DelayMsgController { @Autowired - private CamelliaDelayQueueSdk delayQueueSdk; + private DelayMsgService delayMsgService; - @PostMapping("/put") - public CamelliaDelayMsg sendDelayMsg(@RequestParam("msg") String msg, + @PostMapping("/simple") + @Operation(summary = "发送-简单消息", description = "发送-简单消息") + public CamelliaDelayMsg sendSimpleDelayMsg(@RequestParam("msg") String msg, @RequestParam("delaySeconds") long delaySeconds, @RequestParam(value = "ttlSeconds", required = false, defaultValue = "30") long ttlSeconds, @RequestParam(value = "maxRetry", required = false, defaultValue = "3") int maxRetry) { - String topic = ConsumerService1.TOPIC; - log.info("sendDelayMsg, topic = {}, msg = {}, delaySeconds = {}, ttlSeconds = {}, maxRetry = {}", topic, msg, delaySeconds, ttlSeconds, maxRetry); - return delayQueueSdk.sendMsg(topic, msg, delaySeconds, TimeUnit.SECONDS, ttlSeconds, TimeUnit.SECONDS, maxRetry); + return delayMsgService.sendSimpleDelayMsg(msg, delaySeconds, ttlSeconds, maxRetry); + } + + @PostMapping("/lambda") + @Operation(summary = "发送-Lambda消息", description = "发送-Lambda消息") + public CamelliaDelayMsg sendLambdaDelayMsg(@RequestParam("msg") String msg, + @RequestParam("delaySeconds") long delaySeconds, + @RequestParam(value = "ttlSeconds", required = false, defaultValue = "30") long ttlSeconds, + @RequestParam(value = "maxRetry", required = false, defaultValue = "3") int maxRetry) { + return delayMsgService.sendLambdaDelayMsg(msg, delaySeconds, ttlSeconds, maxRetry); } } diff --git a/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/service/DelayMsgService.java b/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/service/DelayMsgService.java new file mode 100644 index 00000000..b28aa114 --- /dev/null +++ b/carp-examples/carp-camellia-example/src/main/java/cn/sliew/carp/example/camellia/service/DelayMsgService.java @@ -0,0 +1,44 @@ +package cn.sliew.carp.example.camellia.service; + +import cn.sliew.carp.example.camellia.listener.ConsumerService1; +import cn.sliew.carp.framework.common.reflection.JobDetails; +import cn.sliew.carp.framework.common.reflection.JobDetailsAsmGenerator; +import cn.sliew.carp.framework.common.reflection.JobDetailsGenerator; +import cn.sliew.carp.framework.common.reflection.lambdas.JobLambda; +import cn.sliew.milky.common.util.JacksonUtil; +import com.netease.nim.camellia.delayqueue.common.domain.CamelliaDelayMsg; +import com.netease.nim.camellia.delayqueue.sdk.CamelliaDelayQueueSdk; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +public class DelayMsgService { + + @Autowired + private CamelliaDelayQueueSdk delayQueueSdk; + + public CamelliaDelayMsg sendSimpleDelayMsg(String msg, long delaySeconds, long ttlSeconds, int maxRetry) { + String topic = ConsumerService1.TOPIC; + log.info("sendSimpleDelayMsg, topic = {}, msg = {}, delaySeconds = {}, ttlSeconds = {}, maxRetry = {}", topic, msg, delaySeconds, ttlSeconds, maxRetry); + return delayQueueSdk.sendMsg(topic, msg, delaySeconds, TimeUnit.SECONDS, ttlSeconds, TimeUnit.SECONDS, maxRetry); + } + + public CamelliaDelayMsg sendLambdaDelayMsg(String msg, long delaySeconds, long ttlSeconds, int maxRetry) { + return doSendLambdaDelayMsg(() -> System.out.println(msg), delaySeconds, ttlSeconds, maxRetry); + } + + public CamelliaDelayMsg doSendLambdaDelayMsg(JobLambda jobLambda, long delaySeconds, long ttlSeconds, int maxRetry) { + JobDetailsGenerator generator = new JobDetailsAsmGenerator(); + JobDetails jobDetails = generator.toJobDetails(jobLambda); + String msg = JacksonUtil.toJsonString(jobDetails); + String topic = ConsumerService1.TOPIC; + log.info("sendDelayMsg, topic = {}, msg = {}, delaySeconds = {}, ttlSeconds = {}, maxRetry = {}", topic, msg, delaySeconds, ttlSeconds, maxRetry); + return delayQueueSdk.sendMsg(topic, msg, delaySeconds, TimeUnit.SECONDS, ttlSeconds, TimeUnit.SECONDS, maxRetry); + } + + +} diff --git a/carp-examples/carp-hazelcast-example/pom.xml b/carp-examples/carp-hazelcast-example/pom.xml index 4668c533..067430db 100644 --- a/carp-examples/carp-hazelcast-example/pom.xml +++ b/carp-examples/carp-hazelcast-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-hazelcast-example diff --git a/carp-examples/carp-hazelcast-example/src/main/java/cn/sliew/carp/example/hazelcast/controller/CommandController.java b/carp-examples/carp-hazelcast-example/src/main/java/cn/sliew/carp/example/hazelcast/controller/CommandController.java index 72325860..84641823 100644 --- a/carp-examples/carp-hazelcast-example/src/main/java/cn/sliew/carp/example/hazelcast/controller/CommandController.java +++ b/carp-examples/carp-hazelcast-example/src/main/java/cn/sliew/carp/example/hazelcast/controller/CommandController.java @@ -19,6 +19,7 @@ package cn.sliew.carp.example.hazelcast.controller; import cn.sliew.carp.example.hazelcast.service.HazelcastMapService; +import com.hazelcast.map.IMap; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -34,6 +35,7 @@ public class CommandController { @PostMapping("/put") public boolean put(@RequestParam("key") String key, @RequestParam("value") String value) { mapService.getMap("map-command").put(key, value); + IMap map = mapService.getMap(""); return true; } diff --git a/carp-examples/carp-javers-example/pom.xml b/carp-examples/carp-javers-example/pom.xml index 2528a1b5..69b98675 100644 --- a/carp-examples/carp-javers-example/pom.xml +++ b/carp-examples/carp-javers-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-javers-example diff --git a/carp-examples/carp-jobrunr-example/pom.xml b/carp-examples/carp-jobrunr-example/pom.xml index a212fecc..41e15f7a 100644 --- a/carp-examples/carp-jobrunr-example/pom.xml +++ b/carp-examples/carp-jobrunr-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-jobrunr-example diff --git a/carp-examples/carp-jobrunr-example/src/main/java/cn/sliew/carp/example/jobrunr/controller/JobRunrController.java b/carp-examples/carp-jobrunr-example/src/main/java/cn/sliew/carp/example/jobrunr/controller/JobRunrController.java index be017924..746538a5 100644 --- a/carp-examples/carp-jobrunr-example/src/main/java/cn/sliew/carp/example/jobrunr/controller/JobRunrController.java +++ b/carp-examples/carp-jobrunr-example/src/main/java/cn/sliew/carp/example/jobrunr/controller/JobRunrController.java @@ -49,12 +49,24 @@ public String enqueueExampleJob(@RequestParam(value = "name", defaultValue = "Wo } @PutMapping("/enqueue-example-job-with-record") + @Operation(summary = "新增-复杂对象", description = "新增-复杂对象") public String enqueueExampleJobWithRecord(@RequestParam(value = "name", defaultValue = "World") String name) { SampleJobInput sampleJobInput = new SampleJobInput(UUID.randomUUID(), name); final JobId enqueuedJobId = jobScheduler.enqueue(() -> sampleService.sampleJobWithRecordInput(sampleJobInput)); return "Job Enqueued: " + enqueuedJobId.toString(); } + @PutMapping("/enqueue-example-job-pure-lambda") + @Operation(summary = "新增-纯lambda", description = "新增-纯lambda") + public String enqueueExampleJobPureLambda(@RequestParam(value = "name", defaultValue = "World") String name) { + final JobId enqueuedJobId = jobScheduler.enqueue(() -> { + // 只能写一个,如果打印 2 次就报错 + System.out.println("第一次:Hello " + name); +// System.out.println("第二次:Hello " + name); + }); + return "Job Enqueued: " + enqueuedJobId.toString(); + } + @DeleteMapping("/delete-job") @Operation(summary = "删除", description = "删除") public String deleteExampleJob(@RequestParam(value = "id") String jobId) { diff --git a/carp-examples/carp-mongo-example/pom.xml b/carp-examples/carp-mongo-example/pom.xml index b08214c1..4542de78 100644 --- a/carp-examples/carp-mongo-example/pom.xml +++ b/carp-examples/carp-mongo-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-mongo-example diff --git a/carp-examples/carp-pekko-example/pom.xml b/carp-examples/carp-pekko-example/pom.xml index 8725885c..1f1a19ec 100644 --- a/carp-examples/carp-pekko-example/pom.xml +++ b/carp-examples/carp-pekko-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-pekko-example diff --git a/carp-examples/carp-pekko-example/src/main/java/cn/sliew/carp/example/pekko/cluster/distrubuted/Counter.java b/carp-examples/carp-pekko-example/src/main/java/cn/sliew/carp/example/pekko/cluster/distrubuted/Counter.java new file mode 100644 index 00000000..5e16efcc --- /dev/null +++ b/carp-examples/carp-pekko-example/src/main/java/cn/sliew/carp/example/pekko/cluster/distrubuted/Counter.java @@ -0,0 +1,183 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.example.pekko.cluster.distrubuted; + +import org.apache.pekko.actor.typed.ActorRef; +import org.apache.pekko.actor.typed.Behavior; +import org.apache.pekko.actor.typed.javadsl.AbstractBehavior; +import org.apache.pekko.actor.typed.javadsl.ActorContext; +import org.apache.pekko.actor.typed.javadsl.Behaviors; +import org.apache.pekko.actor.typed.javadsl.Receive; +import org.apache.pekko.cluster.ddata.GCounter; +import org.apache.pekko.cluster.ddata.Key; +import org.apache.pekko.cluster.ddata.SelfUniqueAddress; +import org.apache.pekko.cluster.ddata.typed.javadsl.DistributedData; +import org.apache.pekko.cluster.ddata.typed.javadsl.Replicator; +import org.apache.pekko.cluster.ddata.typed.javadsl.ReplicatorMessageAdapter; + +public class Counter extends AbstractBehavior { + interface Command { + } + + enum Increment implements Command { + INSTANCE + } + + public static class GetValue implements Command { + public final ActorRef replyTo; + + public GetValue(ActorRef replyTo) { + this.replyTo = replyTo; + } + } + + public static class GetCachedValue implements Command { + public final ActorRef replyTo; + + public GetCachedValue(ActorRef replyTo) { + this.replyTo = replyTo; + } + } + + enum Unsubscribe implements Command { + INSTANCE + } + + private interface InternalCommand extends Command { + } + + private static class InternalUpdateResponse implements InternalCommand { + final Replicator.UpdateResponse rsp; + + InternalUpdateResponse(Replicator.UpdateResponse rsp) { + this.rsp = rsp; + } + } + + private static class InternalGetResponse implements InternalCommand { + final Replicator.GetResponse rsp; + final ActorRef replyTo; + + InternalGetResponse(Replicator.GetResponse rsp, ActorRef replyTo) { + this.rsp = rsp; + this.replyTo = replyTo; + } + } + + private static final class InternalSubscribeResponse implements InternalCommand { + final Replicator.SubscribeResponse rsp; + + InternalSubscribeResponse(Replicator.SubscribeResponse rsp) { + this.rsp = rsp; + } + } + + public static Behavior create(Key key) { + return Behaviors.setup( + ctx -> + DistributedData.withReplicatorMessageAdapter( + (ReplicatorMessageAdapter replicatorAdapter) -> + new Counter(ctx, replicatorAdapter, key))); + } + + // adapter that turns the response messages from the replicator into our own protocol + private final ReplicatorMessageAdapter replicatorAdapter; + private final SelfUniqueAddress node; + private final Key key; + + private int cachedValue = 0; + + private Counter( + ActorContext context, + ReplicatorMessageAdapter replicatorAdapter, + Key key) { + super(context); + + this.replicatorAdapter = replicatorAdapter; + this.key = key; + this.node = DistributedData.get(context.getSystem()).selfUniqueAddress(); + this.replicatorAdapter.subscribe(this.key, InternalSubscribeResponse::new); + } + + @Override + public Receive createReceive() { + return newReceiveBuilder() + .onMessage(Increment.class, this::onIncrement) + .onMessage(InternalUpdateResponse.class, msg -> Behaviors.same()) + .onMessage(GetValue.class, this::onGetValue) + .onMessage(GetCachedValue.class, this::onGetCachedValue) + .onMessage(Unsubscribe.class, this::onUnsubscribe) + .onMessage(InternalGetResponse.class, this::onInternalGetResponse) + .onMessage(InternalSubscribeResponse.class, this::onInternalSubscribeResponse) + .build(); + } + + private Behavior onIncrement(Increment cmd) { + replicatorAdapter.askUpdate( + askReplyTo -> + new Replicator.Update<>( + key, + GCounter.empty(), + Replicator.writeLocal(), + askReplyTo, + curr -> curr.increment(node, 1)), + InternalUpdateResponse::new); + return this; + } + + private Behavior onGetValue(GetValue cmd) { + replicatorAdapter.askGet( + askReplyTo -> new Replicator.Get<>(key, Replicator.readLocal(), askReplyTo), + rsp -> new InternalGetResponse(rsp, cmd.replyTo)); + + return this; + } + + private Behavior onGetCachedValue(GetCachedValue cmd) { + cmd.replyTo.tell(cachedValue); + return this; + } + + private Behavior onUnsubscribe(Unsubscribe cmd) { + replicatorAdapter.unsubscribe(key); + return this; + } + + private Behavior onInternalGetResponse(InternalGetResponse msg) { + if (msg.rsp instanceof Replicator.GetSuccess) { + int value = ((Replicator.GetSuccess) msg.rsp).get(key).getValue().intValue(); + msg.replyTo.tell(value); + return this; + } else { + // not dealing with failures + return Behaviors.unhandled(); + } + } + + private Behavior onInternalSubscribeResponse(InternalSubscribeResponse msg) { + if (msg.rsp instanceof Replicator.Changed) { + GCounter counter = ((Replicator.Changed) msg.rsp).get(key); + cachedValue = counter.getValue().intValue(); + return this; + } else { + // no deletes + return Behaviors.unhandled(); + } + } +} \ No newline at end of file diff --git a/carp-examples/carp-redisson-example/pom.xml b/carp-examples/carp-redisson-example/pom.xml index b7755bef..72077e14 100644 --- a/carp-examples/carp-redisson-example/pom.xml +++ b/carp-examples/carp-redisson-example/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-examples - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-redisson-example diff --git a/carp-examples/carp-redisson-example/src/main/java/cn/sliew/carp/example/redisson/controller/LockController.java b/carp-examples/carp-redisson-example/src/main/java/cn/sliew/carp/example/redisson/controller/LockController.java new file mode 100644 index 00000000..919015f0 --- /dev/null +++ b/carp-examples/carp-redisson-example/src/main/java/cn/sliew/carp/example/redisson/controller/LockController.java @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.example.redisson.controller; + +import cn.hutool.core.lang.UUID; +import cn.hutool.core.thread.ThreadUtil; +import cn.sliew.carp.example.redisson.service.LockService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.apache.commons.lang3.time.DurationFormatUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import java.time.Duration; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ThreadPoolExecutor; + +@RestController +@RequestMapping("/api/carp/example/redisson/lock") +@Tag(name = "测试模块-Lock") +public class LockController { + + @Autowired + private LockService lockService; + + /** + * 测试自动续期,自动续期有 1 个要点: + * 1.不设置锁ttl,所以会无限续期下去。如果显式指定,则不会生效。 + */ + @PostMapping("/lock-unlock") + @Operation(summary = "加锁-释放锁") + public String lockAndUnlock() throws Exception { + String key = UUID.fastUUID().toString(true); + boolean locked = lockService.lockWithAutoRefreshTTL(key, Duration.ofSeconds(3L).toMillis()); + if (locked) { + System.out.println("lock: " + key); + ThreadUtil.sleep(Duration.ofMinutes(3L).toMillis()); + Long releaseTime = lockService.lockReleaseTime(key); + System.out.println("lock relase time: " + DurationFormatUtils.formatDurationHMS(releaseTime)); + lockService.unlock(key); + return key; + } + return "加锁失败"; + } + + /** + * 测试异步释放锁 + * 1.默认是只有持有锁的线程才可以释放锁,异步情况下,必须强制释放锁才可以 + */ + @PostMapping("/lock-unlock-async") + @Operation(summary = "加锁-异步释放锁") + public String lockAndUnlockAsync() throws Exception { + String key = UUID.fastUUID().toString(true); + boolean locked = lockService.lockWithAutoRefreshTTL(key, Duration.ofSeconds(3L).toMillis()); + if (locked) { + ThreadPoolExecutor executor = ThreadUtil.newExecutor(4); + CompletableFuture future = CompletableFuture.runAsync(() -> { + System.out.println("lock: " + key); + ThreadUtil.sleep(Duration.ofMinutes(1L).toMillis()); + Long releaseTime = lockService.lockReleaseTime(key); + System.out.println("lock relase time: " + DurationFormatUtils.formatDurationHMS(releaseTime)); + }, executor); + future.whenCompleteAsync((unused, throwable) -> { + lockService.forceUnlock(key); + }, executor); + return key; + } + return "加锁失败"; + } + + @PostMapping("/lock") + @Operation(summary = "加锁") + public String lock() throws Exception { + String key = UUID.fastUUID().toString(true); + boolean locked = lockService.lock(key, Duration.ofSeconds(3L).toMillis(), Duration.ofSeconds(10L).toMillis()); + if (locked) { + return key; + } + return "加锁失败"; + } + + @PostMapping("/unlock") + @Operation(summary = "释放锁") + public void unlock(@RequestParam("key") String key) throws Exception { + lockService.unlock(key); + } + + @PostMapping("/forceUnlock") + @Operation(summary = "强制释放锁") + public void forceUnlock(@RequestParam("key") String key) throws Exception { + lockService.forceUnlock(key); + } + + @GetMapping("/lock-ttl") + @Operation(summary = "锁释放时间") + public String scheduleLambda(@RequestParam("key") String key) throws Exception { + Long time = lockService.lockReleaseTime(key); + return DurationFormatUtils.formatDurationHMS(time); + } + +} diff --git a/carp-examples/carp-redisson-example/src/main/java/cn/sliew/carp/example/redisson/service/LockService.java b/carp-examples/carp-redisson-example/src/main/java/cn/sliew/carp/example/redisson/service/LockService.java new file mode 100644 index 00000000..f8e3824e --- /dev/null +++ b/carp-examples/carp-redisson-example/src/main/java/cn/sliew/carp/example/redisson/service/LockService.java @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.example.redisson.service; + +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RLock; +import org.redisson.api.RedissonClient; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import java.util.concurrent.TimeUnit; + +@Slf4j +@Service +public class LockService { + + @Value("${spring.application.name}") + private String application; + + @Autowired + private RedissonClient client; + + /** + * watchDog 只有设置 releaseTime 的 lock 不会生效,不会自动续期 + */ + public boolean lock(String key, long lockTimeout, long releaseTime) { + RLock lock = getLock(key); + try { + // 尝试拿锁 lockTimeout 后停止重试,返回false + // 没有Watch Dog ,releaseTime 后自动释放 + return lock.tryLock(lockTimeout, releaseTime, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } + } + + /** + * watchDog 自动续期时长默认为 30s,可通过 lockWatchdogTimeout 设置每次续期时长。 + * watchDog 按照 lockWatchdogTimeout / 3 的频率检测 key,进行续期 + */ + public boolean lockWithAutoRefreshTTL(String key, long lockTimeout) { + RLock lock = getLock(key); + try { + // 尝试拿锁 lockTimeout 后停止重试,返回false + // 具有Watch Dog 自动延期机制 默认续30s + return lock.tryLock(lockTimeout, TimeUnit.MILLISECONDS); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } + } + + public Long lockReleaseTime(String key) { + RLock lock = getLock(key); + if (lock.isLocked()) { + return lock.remainTimeToLive(); + } + return 0L; + } + + public void unlock(String key) { + RLock lock = getLock(key); + try { + if (lock.isLocked()) { + lock.unlock(); + } + } catch (Exception e) { + log.error("unlock failed, lock: {}", lock.getName(), e); + } + } + + public void forceUnlock(String key) { + RLock lock = getLock(key); + try { + if (lock.isLocked()) { + lock.forceUnlock(); + } + } catch (Exception e) { + log.error("forceUnlock failed, lock: {}", lock.getName(), e); + } + } + + private RLock getLock(String key) { + return client.getLock(appendLockKey(key)); + } + + private String appendLockKey(String key) { + return String.format("%s:lock:%s", application, key); + } +} diff --git a/carp-examples/pom.xml b/carp-examples/pom.xml index f07b7880..70b67b34 100644 --- a/carp-examples/pom.xml +++ b/carp-examples/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-examples diff --git a/carp-framework/carp-framework-biz/pom.xml b/carp-framework/carp-framework-biz/pom.xml new file mode 100644 index 00000000..d1feda48 --- /dev/null +++ b/carp-framework/carp-framework-biz/pom.xml @@ -0,0 +1,51 @@ + + + + + 4.0.0 + + cn.sliew + carp-framework + 0.0.13-SNAPSHOT + ../pom.xml + + carp-framework-biz + + + + ${project.parent.groupId} + carp-framework-mybatis + + + + com.alibaba + easyexcel + provided + + + + jakarta.validation + jakarta.validation-api + provided + + + + + \ No newline at end of file diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/annotation/ExcelImage.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/annotation/ExcelImage.java new file mode 100644 index 00000000..2bdffb02 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/annotation/ExcelImage.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.easyexcel.annotation; + +import com.alibaba.excel.metadata.data.ClientAnchorData; + +import java.lang.annotation.*; + +@Documented +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ExcelImage { + + boolean isMultiple() default false; + + ClientAnchorData.AnchorType anchorType() default ClientAnchorData.AnchorType.MOVE_AND_RESIZE; +} diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/converters/DictConverter.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/converters/DictConverter.java new file mode 100644 index 00000000..84c904a6 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/converters/DictConverter.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.easyexcel.converters; + +import cn.sliew.carp.framework.common.dict.*; +import com.alibaba.excel.converters.Converter; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.exception.ExcelDataConvertException; +import com.alibaba.excel.metadata.GlobalConfiguration; +import com.alibaba.excel.metadata.data.ReadCellData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.metadata.property.ExcelContentProperty; + +import java.util.Objects; +import java.util.Optional; + +public class DictConverter implements Converter { + + private DictRegistry dictRegistry = EnumDictRegistry.INSTANCE; + + @Override + public Class supportJavaTypeKey() { + return DictInstance.class; + } + + @Override + public CellDataTypeEnum supportExcelTypeKey() { + return CellDataTypeEnum.STRING; + } + + @Override + public DictInstance convertToJavaData(ReadCellData cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + String value = cellData.getStringValue(); + try { + Dict dictEnum = contentProperty.getField().getAnnotation(Dict.class); + if (Objects.nonNull(dictEnum) && Objects.nonNull(value)) { + String code = dictEnum.code(); + Optional optional = dictRegistry.getDictDefinition(code); + if (optional.isEmpty()) { + throw new ExcelDataConvertException(cellData.getRowIndex(), cellData.getColumnIndex(), cellData, contentProperty, "unknown dict code"); + } + Optional dictInstance = dictRegistry.getDictInstance(optional.get(), value); + if (dictInstance.isEmpty()) { + throw new ExcelDataConvertException(cellData.getRowIndex(), cellData.getColumnIndex(), cellData, contentProperty, "unknown dict instance code"); + } + return dictInstance.get(); + } + throw new ExcelDataConvertException(cellData.getRowIndex(), cellData.getColumnIndex(), cellData, contentProperty, "field must contains Dict annotation"); + } catch (Exception e) { + throw new ExcelDataConvertException(cellData.getRowIndex(), cellData.getColumnIndex(), cellData, contentProperty, e.getMessage(), e); + } + } + + @Override + public WriteCellData convertToExcelData(DictInstance value, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { + return new WriteCellData(value.getValue()); + } +} diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/handler/ImageCellWriteHandler.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/handler/ImageCellWriteHandler.java new file mode 100644 index 00000000..6d937118 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/easyexcel/handler/ImageCellWriteHandler.java @@ -0,0 +1,158 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.easyexcel.handler; + +import cn.hutool.http.HttpUtil; +import cn.sliew.carp.framework.biz.ext.easyexcel.annotation.ExcelImage; +import com.alibaba.excel.enums.CellDataTypeEnum; +import com.alibaba.excel.metadata.Head; +import com.alibaba.excel.metadata.data.CellData; +import com.alibaba.excel.metadata.data.ImageData; +import com.alibaba.excel.metadata.data.WriteCellData; +import com.alibaba.excel.write.handler.CellWriteHandler; +import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; +import com.alibaba.excel.write.metadata.holder.WriteTableHolder; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.util.Units; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * 使用时需注册一下,才能生效 + */ +public class ImageCellWriteHandler implements CellWriteHandler { + + private List repeats = new ArrayList<>(); + + @Override + public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + + } + + @Override + public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, WriteCellData cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + // 在数据转换成功后 不是 Head 就把类型设置成空 + if (isHead) { + return; + } + //将要插入图片的单元格的type设置为空,下面再填充图片 + Object data = cellData.getData(); + if (cellData.getImageDataList() != null || data instanceof ArrayList) { + cellData.setType(CellDataTypeEnum.EMPTY); + return; + } + // 写入图片 + handlerExcelImage(cellData, cell, head); + } + + private void handlerExcelImage(WriteCellData cellData, Cell cell, Head head) { + ExcelImage excelImage = head.getField().getAnnotation(ExcelImage.class); + String stringValue = cellData.getStringValue(); + if (Objects.nonNull(excelImage) && Objects.nonNull(stringValue)) { + //处理单张图片 + if (!excelImage.isMultiple()) { + cellData.setType(CellDataTypeEnum.RICH_TEXT_STRING); + ImageData imageData = downloadImageData(stringValue, excelImage); + if (Objects.nonNull(imageData)) { + cellData.setImageDataList(Collections.singletonList(imageData)); + } + } else { + cellData.setType(CellDataTypeEnum.EMPTY); + // 默认使用 , 分割 + List list = Arrays.asList(stringValue.replace(",", ",").split(",")); + Sheet sheet = cell.getSheet(); + int maxColumnWidth = Math.max(sheet.getColumnWidth(cell.getColumnIndex()), 240 * 8 * list.size()); + sheet.setColumnWidth(cell.getColumnIndex(), maxColumnWidth); + List imageDataList = list.stream() + .map(u -> downloadImageData(u, excelImage)) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + for (int i = 0; i < imageDataList.size(); i++) { + insertImage(sheet, cell, imageDataList.get(i).getImage(), i); + } + } + } + } + + private ImageData downloadImageData(String strUrl, ExcelImage excelImage) { + byte[] bytes = HttpUtil.downloadBytes(strUrl); + ImageData imageData = new ImageData(); + imageData.setImage(bytes); + imageData.setAnchorType(excelImage.anchorType()); + return imageData; + } + + @Override + public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) { + // 在单元格写入完毕后,自己填充图片 + if (isHead || CollectionUtils.isEmpty(cellDataList)) { + return; + } + WriteCellData writeCellData = cellDataList.get(0); + if (writeCellData.getData() != null && writeCellData.getData() instanceof ArrayList) { + String key = cell.getRowIndex() + "_" + cell.getColumnIndex(); + if (repeats.contains(key)) { + return; + } + repeats.add(key); + List> cellDatas = (List>) writeCellData.getData(); + Sheet sheet = cell.getSheet(); + sheet.getRow(cell.getRowIndex()).setHeight((short) 900); + int maxColumnWidth = Math.max(sheet.getColumnWidth(cell.getColumnIndex()), 240 * 8 * cellDatas.size()); + sheet.setColumnWidth(cell.getColumnIndex(), maxColumnWidth); + for (int i = 0; i < cellDatas.size(); i++) { + insertImage(sheet, cell, cellDatas.get(i).getData(), i); + } + } + } + + private void insertImage(Sheet sheet, Cell cell, byte[] pictureData, int i) { + int picWidth = Units.pixelToEMU(60); + int index = sheet.getWorkbook().addPicture(pictureData, HSSFWorkbook.PICTURE_TYPE_PNG); + Drawing drawing = sheet.getDrawingPatriarch(); + if (drawing == null) { + drawing = sheet.createDrawingPatriarch(); + } + CreationHelper helper = sheet.getWorkbook().getCreationHelper(); + ClientAnchor anchor = helper.createClientAnchor(); + // 设置图片坐标 + anchor.setDx1(picWidth * i); + anchor.setDx2(picWidth + picWidth * i); + anchor.setDy1(0); + anchor.setDy2(0); + //设置图片位置 + anchor.setCol1(cell.getColumnIndex()); + anchor.setCol2(cell.getColumnIndex()); + anchor.setRow1(cell.getRowIndex()); + anchor.setRow2(cell.getRowIndex() + 1); + + // 设置图片可以随着单元格移动 + anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); + drawing.createPicture(anchor, index); + } +} + diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mapstruct/EntityConvert.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mapstruct/EntityConvert.java new file mode 100644 index 00000000..6f2587a1 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mapstruct/EntityConvert.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.mapstruct; + +import cn.sliew.carp.framework.mybatis.entity.BaseAuditDO; +import org.mapstruct.AfterMapping; +import org.mapstruct.MappingTarget; + +public interface EntityConvert { + + @AfterMapping + default void fillAudit(@MappingTarget BaseAuditDO auditDO) { + + } +} diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mybatis/AbstractEncryptTypeHandler.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mybatis/AbstractEncryptTypeHandler.java new file mode 100644 index 00000000..375a7a32 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mybatis/AbstractEncryptTypeHandler.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.mybatis; + +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.StringTypeHandler; + +import java.sql.CallableStatement; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; + +public abstract class AbstractEncryptTypeHandler extends StringTypeHandler { + + @Override + public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException { + super.setNonNullParameter(ps, i, encrypt(parameter), jdbcType); + } + + @Override + public String getNullableResult(ResultSet rs, String columnName) throws SQLException { + String nullableResult = super.getNullableResult(rs, columnName); + if (StringUtils.isNotBlank(nullableResult)) { + return decrypt(nullableResult); + } + return nullableResult; + } + + @Override + public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException { + String nullableResult = super.getNullableResult(rs, columnIndex); + if (StringUtils.isNotBlank(nullableResult)) { + return decrypt(nullableResult); + } + return nullableResult; + } + + @Override + public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { + String nullableResult = super.getNullableResult(cs, columnIndex); + if (StringUtils.isNotBlank(nullableResult)) { + return decrypt(nullableResult); + } + return nullableResult; + } + + protected abstract String encrypt(String input); + + protected abstract String decrypt(String input); +} diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mybatis/AesEncryptTypeHandler.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mybatis/AesEncryptTypeHandler.java new file mode 100644 index 00000000..5a6afbe3 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/mybatis/AesEncryptTypeHandler.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.mybatis; + +import cn.hutool.core.codec.Base64; +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.crypto.SecureUtil; + +public class AesEncryptTypeHandler extends AbstractEncryptTypeHandler { + + @Override + protected String encrypt(String input) { + byte[] encrypt = SecureUtil.aes().encrypt(input); + return Base64.encode(encrypt); + } + + @Override + protected String decrypt(String input) { + byte[] decrypt = SecureUtil.aes().decrypt(Base64.decode(input)); + return new String(decrypt, CharsetUtil.CHARSET_UTF_8); + } +} diff --git a/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/validation/DictConstraint.java b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/validation/DictConstraint.java new file mode 100644 index 00000000..4c685633 --- /dev/null +++ b/carp-framework/carp-framework-biz/src/main/java/cn/sliew/carp/framework/biz/ext/validation/DictConstraint.java @@ -0,0 +1,76 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.biz.ext.validation; + +import cn.sliew.carp.framework.common.dict.DictDefinition; +import cn.sliew.carp.framework.common.dict.EnumDictRegistry; +import jakarta.validation.Constraint; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.Payload; + +import java.lang.annotation.*; +import java.util.Objects; +import java.util.Optional; + +@Documented +@Constraint(validatedBy = DictConstraint.DictValidator.class) +@Target({ElementType.FIELD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface DictConstraint { + + String message() default ""; + + Class[] groups() default {}; + + Class[] payload() default {}; + + String dict(); + + class DictValidator implements ConstraintValidator { + + private DictConstraint constraint; + + @Override + public void initialize(DictConstraint constraint) { + this.constraint = constraint; + } + + @Override + public boolean isValid(String value, ConstraintValidatorContext context) { + if (Objects.isNull(constraint.dict()) || Objects.isNull(value)) { + context.buildConstraintViolationWithTemplate("[Dict Instance] is invalid").addConstraintViolation(); + return false; + } + + Optional optional = EnumDictRegistry.INSTANCE.getDictDefinition(constraint.dict()); + if (optional.isEmpty()) { + context.buildConstraintViolationWithTemplate("[Dict] is invalid").addConstraintViolation(); + return false; + } + if (EnumDictRegistry.INSTANCE.exists(optional.get(), value) == false) { + context.buildConstraintViolationWithTemplate("[Dict Instance] is invalid").addConstraintViolation(); + return false; + } + return true; + } + } + + +} diff --git a/carp-framework/carp-framework-common/pom.xml b/carp-framework/carp-framework-common/pom.xml index 8da24013..20a71f67 100644 --- a/carp-framework/carp-framework-common/pom.xml +++ b/carp-framework/carp-framework-common/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-common @@ -72,6 +72,11 @@ zjsonpatch + + org.ow2.asm + asm + + cn.sliew milky-common diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/Dict.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/Dict.java new file mode 100644 index 00000000..549f986e --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/Dict.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.dict; + +import java.lang.annotation.*; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +@Inherited +public @interface Dict { + + String code(); +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/DictType.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/DictType.java index 7981d8b4..2c939864 100644 --- a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/DictType.java +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/DictType.java @@ -25,6 +25,7 @@ import cn.sliew.carp.framework.common.dict.datasource.RedisMode; import cn.sliew.carp.framework.common.dict.k8s.ClusterStatus; import cn.sliew.carp.framework.common.dict.k8s.ClusterType; +import cn.sliew.carp.framework.common.dict.license.LicenseType; import cn.sliew.carp.framework.common.dict.oam.AppType; import cn.sliew.carp.framework.common.dict.schedule.ScheduleEngineType; import cn.sliew.carp.framework.common.dict.schedule.ScheduleJobType; @@ -44,6 +45,8 @@ public enum DictType implements DictDefinition { YES_OR_NO("yes_or_no", "是否", YesOrNo.class), IS_DELETED("is_delete", "是否删除", IsDeleted.class), + LICENSE_TYPE("license_type", "证书类型", LicenseType.class), + K8S_CLUSTER_TYPE("k8s_cluster_type", "集群类型", ClusterType.class), K8S_CLUSTER_STATUS("k8s_cluster_status", "集群状态", ClusterStatus.class), diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/license/LicenseType.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/license/LicenseType.java new file mode 100644 index 00000000..2c2bc42d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/dict/license/LicenseType.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.dict.license; + +import cn.sliew.carp.framework.common.dict.DictInstance; +import com.baomidou.mybatisplus.annotation.EnumValue; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.util.Arrays; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum LicenseType implements DictInstance { + + TRIAL("trial", "试用"), + PRO("pro", "专业版"), + ENTERPRISE("enterprise", "企业版"), + ; + + @JsonCreator + public static LicenseType of(String value) { + return Arrays.stream(values()) + .filter(instance -> instance.getValue().equals(value)) + .findAny().orElseThrow(() -> new EnumConstantNotPresentException(LicenseType.class, value)); + } + + @EnumValue + private String value; + private String label; + + LicenseType(String value, String label) { + this.value = value; + this.label = label; + } + + @Override + public String getValue() { + return value; + } + + @Override + public String getLabel() { + return label; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/model/IdListParam.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/model/IdListParam.java new file mode 100644 index 00000000..c8a2d131 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/model/IdListParam.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.annotation.Nonnull; +import java.util.List; + +@Data +public class IdListParam { + + @Schema(description = "ids") + @Nonnull + private List ids; +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/model/IdParam.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/model/IdParam.java new file mode 100644 index 00000000..b22434b7 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/model/IdParam.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.model; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import javax.annotation.Nonnull; + +@Data +public class IdParam { + + @Schema(description = "id") + @Nonnull + private Long id; +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/AbstractJobDetailsFinder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/AbstractJobDetailsFinder.java new file mode 100644 index 00000000..e273245a --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/AbstractJobDetailsFinder.java @@ -0,0 +1,118 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.instructions.*; +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; +import cn.sliew.carp.framework.common.util.reflection.JarUtils; +import org.objectweb.asm.*; + +import java.io.IOException; +import java.io.InputStream; + +abstract class AbstractJobDetailsFinder extends ClassVisitor { + + protected final JobDetailsBuilder jobDetailsBuilder; + + protected AbstractJobDetailsFinder(JobDetailsBuilder jobDetailsBuilder) { + super(Opcodes.ASM7); + this.jobDetailsBuilder = jobDetailsBuilder; + } + + @Override + public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { + if (isLambdaContainingJobDetails(name)) { + return new MethodVisitor(Opcodes.ASM7) { + + @Override + public void visitFieldInsn(int opcode, String owner, String name, String descriptor) { + VisitFieldInstruction instruction = AllJVMInstructions.get(opcode, jobDetailsBuilder); + instruction.load(owner, name, descriptor); + } + + @Override + public void visitInvokeDynamicInsn(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { + InvokeDynamicInstruction instruction = AllJVMInstructions.get(Opcodes.INVOKEDYNAMIC, jobDetailsBuilder); + instruction.load(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) { + VisitMethodInstruction visitMethodInstruction = AllJVMInstructions.get(opcode, jobDetailsBuilder); + visitMethodInstruction.load(owner, name, descriptor, isInterface); + } + + @Override + public void visitInsn(int opcode) { + ZeroOperandInstruction zeroOperandInstruction = AllJVMInstructions.get(opcode, jobDetailsBuilder); + zeroOperandInstruction.load(); + } + + @Override + public void visitVarInsn(int opcode, int variable) { + VisitLocalVariableInstruction instruction = AllJVMInstructions.get(opcode, jobDetailsBuilder); + instruction.load(variable); + } + + @Override + public void visitIntInsn(int opcode, int operand) { + SingleIntOperandInstruction singleIntOperandInstruction = AllJVMInstructions.get(opcode, jobDetailsBuilder); + singleIntOperandInstruction.load(operand); + } + + @Override + public void visitLdcInsn(Object value) { + LdcInstruction ldcInstruction = AllJVMInstructions.get(Opcodes.LDC, jobDetailsBuilder); + ldcInstruction.load(value); + } + + @Override + public void visitTypeInsn(int opcode, String type) { + VisitTypeInstruction instruction = AllJVMInstructions.get(opcode, jobDetailsBuilder); + instruction.load(type); + } + }; + } else { + return super.visitMethod(access, name, descriptor, signature, exceptions); + } + } + + protected abstract boolean isLambdaContainingJobDetails(String name); + + protected abstract InputStream getClassContainingLambdaAsInputStream(); + + public JobDetails getJobDetails() { + return jobDetailsBuilder.getJobDetails(); + } + + protected void parse(InputStream inputStream) throws IOException { + try { + ClassReader parser = new ClassReader(inputStream); + parser.accept(this, ClassReader.SKIP_FRAMES); + } catch (IllegalArgumentException e) { + if(e.getMessage().startsWith("Unsupported class file")) { + String requiredAsmVersion = JarUtils.getManifestAttributeValue(JobRunrJob.class, "Minimum-ASM-Version"); + String actualAsmVersion = JarUtils.getVersion(Opcodes.class); + throw new IllegalArgumentException("JobRunr needs (and automatically adds) ASM " + requiredAsmVersion + " as a transitive dependency but you have ASM " + actualAsmVersion + " on the classpath.", e); + } + throw e; + } + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/CachingJobDetailsGenerator.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/CachingJobDetailsGenerator.java new file mode 100644 index 00000000..f504d637 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/CachingJobDetailsGenerator.java @@ -0,0 +1,253 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.IocJobLambda; +import cn.sliew.carp.framework.common.reflection.lambdas.JobLambda; +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; +import cn.sliew.milky.common.exception.Rethrower; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static java.lang.Boolean.TRUE; +import static java.util.Arrays.asList; +import static java.util.Arrays.stream; +import static java.util.Collections.emptyList; + +public class CachingJobDetailsGenerator implements JobDetailsGenerator { + + private final JobDetailsGenerator delegate; + private final Map, CacheableJobDetails> cache; + + public CachingJobDetailsGenerator() { + this(new JobDetailsAsmGenerator()); + } + + public CachingJobDetailsGenerator(JobDetailsGenerator delegate) { + this.delegate = delegate; + this.cache = new ConcurrentHashMap<>(); + } + + @Override + public JobDetails toJobDetails(JobLambda lambda) { + return cache + .computeIfAbsent(lambda.getClass(), clazz -> new CacheableJobDetails(delegate)) + .getJobDetails(lambda); + } + + @Override + public JobDetails toJobDetails(IocJobLambda lambda) { + return cache + .computeIfAbsent(lambda.getClass(), clazz -> new CacheableJobDetails(delegate)) + .getJobDetails(lambda); + } + + private static class CacheableJobDetails { + + private static final MethodHandles.Lookup lookup = MethodHandles.lookup(); + private final JobDetailsGenerator jobDetailsGeneratorDelegate; + private volatile JobDetails jobDetails; + private List jobParameterRetrievers; + + private CacheableJobDetails(JobDetailsGenerator jobDetailsGeneratorDelegate) { + this.jobDetailsGeneratorDelegate = jobDetailsGeneratorDelegate; + } + + public JobDetails getJobDetails(JobLambda lambda) { + return initOrGetJobDetails( + () -> jobDetailsGeneratorDelegate.toJobDetails(lambda), + () -> initJobParameterRetrievers(jobDetails, lambda, Optional.empty()), + () -> getCachedJobDetails(lambda, Optional.empty())); + } + + public JobDetails getJobDetails(IocJobLambda lambda) { + return initOrGetJobDetails( + () -> jobDetailsGeneratorDelegate.toJobDetails(lambda), + () -> initJobParameterRetrievers(jobDetails, lambda, Optional.empty()), + () -> getCachedJobDetails(lambda, Optional.empty())); + } + + private JobDetails initOrGetJobDetails(Supplier jobDetailsSupplier, Supplier> jobParameterRetrieverSupplier, Supplier getJobDetailsUsingCache) { + if (this.jobDetails == null) { + JobDetails jobDetails = initJobDetails(jobDetailsSupplier, jobParameterRetrieverSupplier); + if (jobDetails != null) return jobDetails; + } + + if (TRUE.equals(this.jobDetails.getCacheable())) { + return getJobDetailsUsingCache.get(); + } else { + return jobDetailsSupplier.get(); + } + } + + /** + * On first initialization, this creates the JobDetails, determines whether it is cacheable and returns it. + * + * @param jobDetailsSupplier a Supplier to use when the {@link JobDetails} are null. + * @param jobParameterRetrieverSupplier a Supplier to use when the List of {@link JobParameterRetriever JobParameterRetrievers} are null. + * @return JobDetails if it was just initialized, null otherwise. + */ + private synchronized JobDetails initJobDetails(Supplier jobDetailsSupplier, Supplier> jobParameterRetrieverSupplier) { + if (this.jobDetails == null) { + this.jobDetails = jobDetailsSupplier.get(); + jobParameterRetrievers = jobParameterRetrieverSupplier.get(); + return this.jobDetails; + } + return null; + } + + private static List initJobParameterRetrievers(JobDetails jobDetails, JobRunrJob jobRunrJob, Optional itemFromStream) { + try { + List parameterRetrievers = new ArrayList<>(); + List declaredFields = new ArrayList<>(asList(jobRunrJob.getClass().getDeclaredFields())); + List jobParameters = jobDetails.getJobParameters(); + + if (isParentClassPassedAsFieldToPassJobDetailsClass(declaredFields, jobDetails) + || isClassPassedAsFieldToPassJobDetailsClass(declaredFields, jobDetails)) { + declaredFields.remove(0); + } + + for (JobParameter jp : jobParameters) { + parameterRetrievers.add(createJobParameterRetriever(jp, jobRunrJob, itemFromStream, declaredFields)); + } + + jobDetails.setCacheable( + declaredFields.isEmpty() + && jobParameters.size() == parameterRetrievers.size() + && (!itemFromStream.isPresent() || parameterRetrievers.stream().anyMatch(r -> r instanceof ItemFromStreamJobParameterRetriever)) + ); + return parameterRetrievers; + } catch (Exception e) { + jobDetails.setCacheable(false); + return emptyList(); + } + } + + + private static boolean isParentClassPassedAsFieldToPassJobDetailsClass(List declaredFields, JobDetails jobDetails) { + if (declaredFields.isEmpty()) return false; + + Class jobDetailsClass = ReflectionUtils.toClass(jobDetails.getClassName()); + + return stream(declaredFields.get(0).getType().getDeclaredFields()) + .map(Field::getType) + .anyMatch(x -> x.isAssignableFrom(jobDetailsClass)); + } + + private static boolean isClassPassedAsFieldToPassJobDetailsClass(List declaredFields, JobDetails jobDetails) { + if (declaredFields.isEmpty()) return false; + + return declaredFields.get(0).getType().getName().equals(jobDetails.getClassName()); + } + + private static JobParameterRetriever createJobParameterRetriever(JobParameter jp, JobRunrJob jobRunrJob, Optional itemFromStream, List declaredFields) throws IllegalAccessException { + JobParameterRetriever jobParameterRetriever = new FixedJobParameterRetriever(jp); + if (itemFromStream.isPresent() && jp.getObject().equals(itemFromStream.get())) { + jobParameterRetriever = new ItemFromStreamJobParameterRetriever(jp); + } else { + final ListIterator fieldIterator = declaredFields.listIterator(); + while (fieldIterator.hasNext()) { + Field f = fieldIterator.next(); + Object valueFromField = ReflectionUtils.getValueFromField(f, jobRunrJob); + if (jp.getObject().equals(valueFromField)) { + MethodHandle e = lookup.unreflectGetter(f); + jobParameterRetriever = new MethodHandleJobParameterRetriever(jp, e.asType(e.type().generic())); + fieldIterator.remove(); + break; + } + } + } + return jobParameterRetriever; + } + + private JobDetails getCachedJobDetails(JobRunrJob job, Optional itemFromStream) { + final JobDetails cachedJobDetails = new JobDetails( + this.jobDetails.getClassName(), + this.jobDetails.getStaticFieldName(), + this.jobDetails.getMethodName(), + jobParameterRetrievers.stream() + .map(jobParameterRetriever -> jobParameterRetriever.getJobParameter(job, itemFromStream)) + .collect(Collectors.toList()) + ); + cachedJobDetails.setCacheable(true); + return cachedJobDetails; + } + } + + private interface JobParameterRetriever { + JobParameter getJobParameter(JobRunrJob job, Optional itemFromStream); + } + + private static class FixedJobParameterRetriever implements JobParameterRetriever { + + private final JobParameter jobParameter; + + public FixedJobParameterRetriever(JobParameter jobParameter) { + this.jobParameter = jobParameter; + } + + @Override + public JobParameter getJobParameter(JobRunrJob job, Optional itemFromStream) { + return jobParameter; + } + } + + private static class MethodHandleJobParameterRetriever implements JobParameterRetriever { + + private final String jobParameterClassName; + private final MethodHandle methodHandle; + + public MethodHandleJobParameterRetriever(JobParameter jobParameter, MethodHandle methodHandle) { + this.jobParameterClassName = jobParameter.getClassName(); + this.methodHandle = methodHandle; + } + + @Override + public JobParameter getJobParameter(JobRunrJob job, Optional itemFromStream) { + try { + Object o = methodHandle.invokeExact((Object) job); + return new JobParameter(jobParameterClassName, o); + } catch (Throwable throwable) { + Rethrower.throwAs(throwable); + return null; + } + } + } + + private static class ItemFromStreamJobParameterRetriever implements JobParameterRetriever { + + private final String jobParameterClassName; + + public ItemFromStreamJobParameterRetriever(JobParameter jobParameter) { + this.jobParameterClassName = jobParameter.getClassName(); + } + + @Override + public JobParameter getJobParameter(JobRunrJob job, Optional itemFromStream) { + return new JobParameter(jobParameterClassName, itemFromStream.orElseThrow(() -> new IllegalStateException("Can not find itemFromStream"))); + } + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JavaJobDetailsBuilder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JavaJobDetailsBuilder.java new file mode 100644 index 00000000..56b9234a --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JavaJobDetailsBuilder.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.IocJobLambda; + +import java.lang.invoke.MethodHandleInfo; +import java.lang.invoke.SerializedLambda; +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; + +public class JavaJobDetailsBuilder extends JobDetailsBuilder { + + public JavaJobDetailsBuilder(SerializedLambda serializedLambda, Object... params) { + super(initLocalVariables(serializedLambda, params), JobDetailsGeneratorUtils.toFQClassName(serializedLambda.getImplClass()), serializedLambda.getImplMethodName()); + } + + protected static List initLocalVariables(SerializedLambda serializedLambda, Object[] params) { + List result = new ArrayList<>(); + final Class[] paramTypesFromDescriptor = JobDetailsGeneratorUtils.findParamTypesFromDescriptorAsArray(serializedLambda.getImplMethodSignature()); + final boolean isIoCJobLambda = IocJobLambda.class.getName().equals(JobDetailsGeneratorUtils.toFQClassName(serializedLambda.getFunctionalInterfaceClass())); + for (int i = 0; i < serializedLambda.getCapturedArgCount(); i++) { + final Object capturedArg = serializedLambda.getCapturedArg(i); + result.add(capturedArg); + if (isPrimitiveLongOrDouble(serializedLambda.getImplMethodKind(), paramTypesFromDescriptor, i, capturedArg)) { //why: If the local variable at index is of type double or long, it occupies both index and index + 1. See https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html + result.add(null); + } + } + result.addAll(asList(params)); + if (isIoCJobLambda) { + result.add(null); // will be injected by IoC + } + return result; + } + + private static boolean isPrimitiveLongOrDouble(int implMethodKind, Class[] paramTypesFromDescriptor, int captureArgCounter, Object capturedArg) { + if (MethodHandleInfo.REF_invokeStatic == implMethodKind) { + return isPrimitiveLongOrDouble(paramTypesFromDescriptor[captureArgCounter], capturedArg); + } else if (MethodHandleInfo.REF_invokeVirtual == implMethodKind || MethodHandleInfo.REF_invokeSpecial == implMethodKind || MethodHandleInfo.REF_invokeInterface == implMethodKind) { + return captureArgCounter > 0 && isPrimitiveLongOrDouble(paramTypesFromDescriptor[captureArgCounter - 1], capturedArg); + } + return false; + } + + private static boolean isPrimitiveLongOrDouble(Class paramTypeFromDescriptor, Object capturedArg) { + return paramTypeFromDescriptor.isPrimitive() && (capturedArg instanceof Long || capturedArg instanceof Double); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JavaJobDetailsFinder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JavaJobDetailsFinder.java new file mode 100644 index 00000000..273e8ba4 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JavaJobDetailsFinder.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; +import cn.sliew.milky.common.exception.Rethrower; +import org.apache.commons.lang3.StringUtils; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.invoke.SerializedLambda; + +import static java.util.Arrays.stream; + +public class JavaJobDetailsFinder extends AbstractJobDetailsFinder { + + private final JobRunrJob jobRunrJob; + private final SerializedLambda serializedLambda; + private final boolean isLambda; + + JavaJobDetailsFinder(JobRunrJob jobRunrJob, SerializedLambda serializedLambda, Object... params) { + super(new JavaJobDetailsBuilder(serializedLambda, params)); + this.jobRunrJob = jobRunrJob; + this.serializedLambda = serializedLambda; + this.isLambda = (serializedLambda.getImplMethodName().startsWith("lambda$") || serializedLambda.getImplMethodName().contains("$lambda-") || serializedLambda.getImplMethodName().contains("$lambda$")); + if (isLambda) { + try (InputStream classContainingLambdaInputStream = getClassContainingLambdaAsInputStream()) { + parse(classContainingLambdaInputStream); + } catch (IOException e) { + Rethrower.throwAs(e); + } + } else if (serializedLambda.getCapturedArgCount() == 1 && + stream(serializedLambda.getCapturedArg(0).getClass().getAnnotations()) + .anyMatch(ann -> "kotlin.Metadata".equals(ann.annotationType().getName()))) { + // kotlin method reference + this.jobDetailsBuilder.setClassName(serializedLambda.getCapturedArg(0).getClass().getName()); + this.jobDetailsBuilder.setMethodName(serializedLambda.getImplMethodName().contains("$") ? + StringUtils.substringAfter(serializedLambda.getImplMethodName(), "$") + : serializedLambda.getImplMethodName()); + } + } + + @Override + protected boolean isLambdaContainingJobDetails(String name) { + return isLambda && name.equals(serializedLambda.getImplMethodName()); + } + + @Override + protected InputStream getClassContainingLambdaAsInputStream() { + return JobDetailsGeneratorUtils.getJavaClassContainingLambdaAsInputStream(jobRunrJob); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetails.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetails.java new file mode 100644 index 00000000..6ba38d83 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetails.java @@ -0,0 +1,89 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Collections.unmodifiableList; + +public class JobDetails { + + private final String className; + private final String staticFieldName; + private final String methodName; + private final ArrayList jobParameters; + private Boolean cacheable; + + private JobDetails() { + this(null, null, null, null); + // used for deserialization + } + + public JobDetails(String className, String staticFieldName, String methodName, List jobParameters) { + this.className = className; + this.staticFieldName = staticFieldName; + this.methodName = methodName; + this.jobParameters = new ArrayList<>(jobParameters); + this.cacheable = false; + } + + public String getClassName() { + return className; + } + + public String getStaticFieldName() { + return staticFieldName; + } + + public boolean hasStaticFieldName() { + return staticFieldName != null; + } + + public String getMethodName() { + return methodName; + } + + public List getJobParameters() { + return unmodifiableList(jobParameters); + } + + public Class[] getJobParameterTypes() { + return jobParameters.stream() + .map(JobParameter::getClassName) + .map(ReflectionUtils::toClass) + .toArray(Class[]::new); + } + + public Object[] getJobParameterValues() { + return jobParameters.stream() + .map(JobParameter::getObject) + .toArray(); + } + + public Boolean getCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsAsmGenerator.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsAsmGenerator.java new file mode 100644 index 00000000..e2a468db --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsAsmGenerator.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.IocJobLambda; +import cn.sliew.carp.framework.common.reflection.lambdas.JobLambda; +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; +import cn.sliew.carp.framework.common.util.reflection.SerializedLambdaUtil; + +import java.lang.annotation.Annotation; + +import static java.util.Arrays.stream; + +public class JobDetailsAsmGenerator implements JobDetailsGenerator { + + @Override + public JobDetails toJobDetails(JobLambda lambda) { + if (isKotlinLambda(lambda)) { + return new KotlinJobDetailsFinder(lambda).getJobDetails(); + } else { + return new JavaJobDetailsFinder(lambda, SerializedLambdaUtil.toSerializedLambda(lambda)).getJobDetails(); + } + } + + @Override + public JobDetails toJobDetails(IocJobLambda lambda) { + if (isKotlinLambda(lambda)) { + return new KotlinJobDetailsFinder(lambda, new Object()).getJobDetails(); + } else { + return new JavaJobDetailsFinder(lambda, SerializedLambdaUtil.toSerializedLambda(lambda)).getJobDetails(); + } + } + + private boolean isKotlinLambda(T lambda) { + return stream(lambda.getClass().getAnnotations()).map(Annotation::annotationType).anyMatch(annotationType -> annotationType.getName().equals("kotlin.Metadata")); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsBuilder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsBuilder.java new file mode 100644 index 00000000..357fcd62 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsBuilder.java @@ -0,0 +1,134 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.instructions.AbstractJVMInstruction; +import cn.sliew.carp.framework.common.reflection.postprocess.CGLibPostProcessor; +import cn.sliew.carp.framework.common.reflection.postprocess.JobDetailsPostProcessor; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import static java.util.Collections.singletonList; + +public abstract class JobDetailsBuilder { + + private final LinkedList instructions; + private final LinkedList stack; + private final List localVariables; + private String jobDetailsClassName; + private String jobDetailsStaticFieldName; + private String jobDetailsMethodName; + private List jobDetailsJobParameters; + private List jobDetailsPostProcessors; + + protected JobDetailsBuilder(List localVariables) { + this(localVariables, null, null); + } + + protected JobDetailsBuilder(List localVariables, String className, String methodName) { + this.instructions = new LinkedList<>(); + this.stack = new LinkedList<>(); + this.localVariables = localVariables; + + setClassName(className); + setMethodName(methodName); + setJobParameters(new ArrayList<>()); + jobDetailsPostProcessors = singletonList(new CGLibPostProcessor()); + } + + public void pushInstructionOnStack(AbstractJVMInstruction jvmInstruction) { + instructions.add(jvmInstruction); + } + + public Object getLocalVariable(int nbrInStack) { + if (nbrInStack < localVariables.size()) { + return localVariables.get(nbrInStack); + } + throw new IllegalStateException("Can not find variable " + nbrInStack + " in stack"); + } + + public void addLocalVariable(Object o) { + this.localVariables.add(o); + } + + public List getInstructions() { + return instructions; + } + + public AbstractJVMInstruction pollFirstInstruction() { + return instructions.pollFirst(); + } + + public LinkedList getStack() { + return stack; + } + + public JobDetails getJobDetails() { + invokeInstructions(); + final JobDetails jobDetails = new JobDetails(jobDetailsClassName, jobDetailsStaticFieldName, jobDetailsMethodName, jobDetailsJobParameters); + return postProcessJobDetails(jobDetails); + } + + private JobDetails postProcessJobDetails(JobDetails jobDetails) { + JobDetails currentJobDetails = jobDetails; + for (JobDetailsPostProcessor postProcessor : getJobDetailsPostProcessors()) { + currentJobDetails = postProcessor.postProcess(currentJobDetails); + } + return currentJobDetails; + } + + private void invokeInstructions() { + if (instructions.isEmpty() && localVariables.size() > 1) { // it is a method reference + for (int i = 1; i < localVariables.size(); i++) { + Object variable = localVariables.get(i); + jobDetailsJobParameters.add(new JobParameter(variable)); + } + } else { + AbstractJVMInstruction instruction = pollFirstInstruction(); + while (instruction != null) { + instruction.invokeInstructionAndPushOnStack(); + instruction = pollFirstInstruction(); + } + } + } + + public void setClassName(String className) { + if (jobDetailsStaticFieldName == null) { + jobDetailsClassName = className; + } + } + + public void setStaticFieldName(String name) { + jobDetailsStaticFieldName = name; + } + + public void setMethodName(String name) { + jobDetailsMethodName = name; + } + + public void setJobParameters(List jobParameters) { + jobDetailsJobParameters = jobParameters; + } + + List getJobDetailsPostProcessors() { + return jobDetailsPostProcessors; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsGenerator.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsGenerator.java new file mode 100644 index 00000000..e7049fe7 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsGenerator.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.IocJobLambda; +import cn.sliew.carp.framework.common.reflection.lambdas.JobLambda; +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; + +public interface JobDetailsGenerator { + + JobDetails toJobDetails(JobLambda lambda); + + JobDetails toJobDetails(IocJobLambda lambda); + + default JobDetails toJobDetails(JobRunrJob jobRunrJob) { + if(jobRunrJob instanceof JobLambda) { + return toJobDetails((JobLambda) jobRunrJob); + } else if(jobRunrJob instanceof IocJobLambda) { + return toJobDetails((IocJobLambda) jobRunrJob); + } + throw new IllegalArgumentException("The provided JobRunr job is not a valid JobRunr Job."); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsGeneratorUtils.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsGeneratorUtils.java new file mode 100644 index 00000000..5296a4e5 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobDetailsGeneratorUtils.java @@ -0,0 +1,166 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; +import cn.sliew.milky.common.exception.Rethrower; + +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class JobDetailsGeneratorUtils { + + private static Pattern PARAM_TYPES_PATTERN = Pattern.compile("\\[*L[^;]+;|\\[[ZBCSIFDJ]|[ZBCSIFDJ]"); //Regex for desc \[*L[^;]+;|\[[ZBCSIFDJ]|[ZBCSIFDJ] + + private JobDetailsGeneratorUtils() { + } + + public static String toFQClassName(String byteCodeName) { + return byteCodeName.replace("/", "."); + } + + public static String toFQResource(String byteCodeName) { + return byteCodeName.replace(".", "/"); + } + + public static InputStream getJavaClassContainingLambdaAsInputStream(Object lambda) { + String location = getClassLocationOfLambda(lambda); + return lambda.getClass().getResourceAsStream(location); + } + + public static InputStream getKotlinClassContainingLambdaAsInputStream(Object lambda) { + String name = lambda.getClass().getName(); + String location = "/" + toFQResource(name) + ".class"; + return lambda.getClass().getResourceAsStream(location); + } + + public static String getClassLocationOfLambda(Object lambda) { + String name = lambda.getClass().getName(); + return "/" + toFQResource(name.substring(0, name.indexOf("$$"))) + ".class"; + } + + public static Object createObjectViaConstructor(String fqClassName, Class[] paramTypes, Object[] parameters) { + try { + Class clazz = ReflectionUtils.loadClass(fqClassName); + Constructor constructor = clazz.getDeclaredConstructor(paramTypes); + return constructor.newInstance(parameters); + } catch (Exception e) { + Rethrower.throwAs(e); + return null; + } + } + + public static Object createObjectViaMethod(Object objectWithMethodToInvoke, String methodName, Class[] paramTypes, Object[] parameters) { + try { + Class clazz = objectWithMethodToInvoke.getClass(); + if (clazz.isSynthetic()) + throw new IllegalArgumentException("You are passing another (nested) Java 8 lambda to JobRunr - this is not supported. Try to convert your lambda to a class or a method."); + Method method = ReflectionUtils.getMethod(clazz, methodName, paramTypes); + ReflectionUtils.makeAccessible(method); + return method.invoke(objectWithMethodToInvoke, parameters); + } catch (IllegalArgumentException e) { + throw e; + } catch (Exception e) { + Rethrower.throwAs(e); + return null; + } + } + + public static Object createObjectViaStaticMethod(String fqClassName, String methodName, Class[] paramTypes, Object[] parameters) { + try { + Class clazz = ReflectionUtils.loadClass(fqClassName); + Method method = ReflectionUtils.getMethod(clazz, methodName, paramTypes); + return method.invoke(null, parameters); + } catch (Exception e) { + Rethrower.throwAs(e); + return null; + } + } + + public static Object getObjectViaStaticField(String fqClassName, String fieldName) { + try { + Class clazz = ReflectionUtils.loadClass(fqClassName); + Field field = ReflectionUtils.getField(clazz, fieldName); + ReflectionUtils.makeAccessible(field); + return field.get(null); + } catch (Exception e) { + Rethrower.throwAs(e); + return null; + } + } + + public static Object getObjectViaField(Object object, String fieldName) { + try { + Class clazz = object.getClass(); + Field field = ReflectionUtils.getField(clazz, fieldName); + ReflectionUtils.makeAccessible(field); + return field.get(object); + } catch (Exception e) { + Rethrower.throwAs(e); + return null; + } + } + + public static Class[] findParamTypesFromDescriptorAsArray(String desc) { + return findParamTypesFromDescriptor(desc).toArray(new Class[0]); + } + + public static List> findParamTypesFromDescriptor(String desc) { + int beginIndex = desc.indexOf('('); + int endIndex = desc.lastIndexOf(')'); + + if ((beginIndex == -1 && endIndex != -1) || (beginIndex != -1 && endIndex == -1)) { + throw new IllegalStateException("Could not find the parameterTypes in the descriptor " + desc); + } + String x0; + if (beginIndex == -1 && endIndex == -1) { + x0 = desc; + } else { + x0 = desc.substring(beginIndex + 1, endIndex); + } + Matcher matcher = PARAM_TYPES_PATTERN.matcher(x0); + List> paramTypes = new ArrayList<>(); + while (matcher.find()) { + String paramType = matcher.group(); + Class clazzToAdd = getClassToAdd(paramType); + paramTypes.add(clazzToAdd); + } + return paramTypes; + } + + private static Class getClassToAdd(String paramType) { + if ("Z".equals(paramType)) return boolean.class; + else if ("I".equals(paramType)) return int.class; + else if ("J".equals(paramType)) return long.class; + else if ("F".equals(paramType)) return float.class; + else if ("D".equals(paramType)) return double.class; + else if ("B".equals(paramType) || "S".equals(paramType) || "C".equals(paramType)) + throw new IllegalStateException("Error parsing lambda", new IllegalArgumentException("Parameters of type byte, short and char are not supported currently.")); + else if (paramType.startsWith("L")) + return ReflectionUtils.toClass(toFQClassName(paramType.substring(1).replace(";", ""))); + else if (paramType.startsWith("[")) return ReflectionUtils.toClass(toFQClassName(paramType)); + else throw new IllegalStateException("A classType was found which is not known: " + paramType); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobParameter.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobParameter.java new file mode 100644 index 00000000..c3455ca3 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/JobParameter.java @@ -0,0 +1,84 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +public class JobParameter { + + private String className; + private String actualClassName; + private Object object; + + private JobParameter() { + // used for deserialization + } + + private JobParameter(Class clazz) { + this(clazz.getName(), null); + } + + public JobParameter(Class clazz, Object object) { + this(clazz.getName(), object); + } + + public JobParameter(Object object) { + this(object.getClass().getName(), object); + } + + public JobParameter(String className, Object object) { + this(className, isNotNullNorAnEnum(object) ? object.getClass().getName() : className, object); + } + + public JobParameter(String className, String actualClassName, Object object) { + this.className = className; + this.actualClassName = actualClassName; + this.object = object; + } + + /** + * Represents the class name expected by the job method (e.g. an object or an interface) + * + * @return the class name expected by the job method (e.g. an object or an interface) + */ + public String getClassName() { + return className; + } + + /** + * Represents the actual class name of the job parameter (e.g. an object), this will never be an interface + * + * @return the actual class name of the job parameter (e.g. an object), this will never be an interface + */ + public String getActualClassName() { + return actualClassName; + } + + /** + * The actual job parameter + * + * @return the actual job parameter + */ + public Object getObject() { + return object; + } + + + protected static boolean isNotNullNorAnEnum(Object object) { + return object != null && !(object instanceof Enum); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/KotlinJobDetailsBuilder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/KotlinJobDetailsBuilder.java new file mode 100644 index 00000000..e9418019 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/KotlinJobDetailsBuilder.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; + +import java.util.ArrayList; +import java.util.List; + +import static java.util.Arrays.asList; + +public class KotlinJobDetailsBuilder extends JobDetailsBuilder { + + public KotlinJobDetailsBuilder(JobRunrJob jobRunrJob, Object... params) { + super(getLocalVariables(jobRunrJob, params)); + } + + private static List getLocalVariables(JobRunrJob jobRunrJob, Object... params) { + List result = new ArrayList<>(); + result.add(jobRunrJob); + result.addAll(asList(params)); + return result; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/KotlinJobDetailsFinder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/KotlinJobDetailsFinder.java new file mode 100644 index 00000000..cf4c920d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/KotlinJobDetailsFinder.java @@ -0,0 +1,141 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection; + +import cn.sliew.carp.framework.common.reflection.lambdas.JobRunrJob; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; +import cn.sliew.milky.common.exception.Rethrower; +import org.objectweb.asm.AnnotationVisitor; +import org.objectweb.asm.Opcodes; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Field; +import java.util.Optional; + +public class KotlinJobDetailsFinder extends AbstractJobDetailsFinder { + + private static final String INVOKE = "invoke"; + private static final String ACCEPT = "accept"; + private static final String RUN = "run"; + + private enum KotlinVersion { + ONE_FOUR, + ONE_FIVE, + ONE_SIX + } + + private final JobRunrJob jobRunrJob; + private int methodCounter = 0; + private KotlinVersion kotlinVersion; + + private String nestedKotlinClassWithMethodReference; + + KotlinJobDetailsFinder(JobRunrJob jobRunrJob, Object... params) { + super(new KotlinJobDetailsBuilder(jobRunrJob, params)); + this.jobRunrJob = jobRunrJob; + try (InputStream classContainingLambdaInputStream = getClassContainingLambdaAsInputStream()) { + parse(classContainingLambdaInputStream); + } catch (IOException e) { + Rethrower.throwAs(e); + } + } + + @Override + public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) { + return new AnnotationVisitor(Opcodes.ASM7) { + @Override + public void visit(String name, Object value) { + if ("mv".equals(name)) { + int[] version = ReflectionUtils.cast(value); + if (version[0] == 1 && version[1] == 4) { + kotlinVersion = KotlinVersion.ONE_FOUR; + } else if (version[0] == 1 && version[1] == 5) { + kotlinVersion = KotlinVersion.ONE_FIVE; + } else if (version[0] == 1 && version[1] == 6) { + kotlinVersion = KotlinVersion.ONE_SIX; + } else { + throw new UnsupportedOperationException("The Kotlin version " + version[0] + "." + version[1] + " is unsupported"); + } + } + } + }; + } + + @Override + protected boolean isLambdaContainingJobDetails(String name) { + if (name.equals(ACCEPT) || name.equals(INVOKE)) { + methodCounter++; + } + if (KotlinVersion.ONE_FOUR.equals(kotlinVersion)) { + return name.equals(RUN) || ((name.equals(ACCEPT) || name.equals(INVOKE)) && methodCounter == 2); + } else { + return name.equals(RUN) || ((name.equals(ACCEPT) || name.equals(INVOKE)) && methodCounter == 1); + } + } + + @Override + public void visitInnerClass(String name, String outerName, String innerName, int access) { + if (access == 0x1018 || access == 0x1000) { + this.nestedKotlinClassWithMethodReference = name; + } + } + + @Override + protected InputStream getClassContainingLambdaAsInputStream() { + return JobDetailsGeneratorUtils.getKotlinClassContainingLambdaAsInputStream(jobRunrJob); + } + + @Override + protected void parse(InputStream inputStream) throws IOException { + Optional field = ReflectionUtils.findField(jobRunrJob.getClass(), "function"); + if (field.isPresent()) { + getJobDetailsFromKotlinFunction(field.get()); + } else { + super.parse(inputStream); + parseNestedClassIfItIsAMethodReference(); + } + } + + private void getJobDetailsFromKotlinFunction(Field field) { + Object function = ReflectionUtils.getValueFromField(field, jobRunrJob); + Field receiver = ReflectionUtils.getField(function.getClass(), "receiver"); + Field name = ReflectionUtils.getField(function.getClass(), "name"); + Class receiverClass = ReflectionUtils.getValueFromField(receiver, function).getClass(); + String methodName = ReflectionUtils.cast(ReflectionUtils.getValueFromField(name, function)); + jobDetailsBuilder.setClassName(receiverClass.getName()); + jobDetailsBuilder.setMethodName(methodName); + } + + private void parseNestedClassIfItIsAMethodReference() throws IOException { + boolean isNestedKotlinClassWithMethodReference = nestedKotlinClassWithMethodReference != null + && !JobDetailsGeneratorUtils.toFQResource(jobRunrJob.getClass().getName()).equals(nestedKotlinClassWithMethodReference); + + if (isNestedKotlinClassWithMethodReference) { + String location = "/" + nestedKotlinClassWithMethodReference + ".class"; + try (InputStream inputStream = jobRunrJob.getClass().getResourceAsStream(location)) { + super.parse(inputStream); + while (jobDetailsBuilder.getInstructions().size() > 1) { + jobDetailsBuilder.pollFirstInstruction(); + } + } + } + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AAStoreInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AAStoreInstruction.java new file mode 100644 index 00000000..b5c590d7 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AAStoreInstruction.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class AAStoreInstruction extends ZeroOperandInstruction { + + public AAStoreInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + Object value = jobDetailsBuilder.getStack().pollLast(); + int index = (int) jobDetailsBuilder.getStack().pollLast(); + Object[] array = (Object[]) jobDetailsBuilder.getStack().pollLast(); + array[index] = value; + return DO_NOT_PUT_ON_STACK; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ALoadOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ALoadOperandInstruction.java new file mode 100644 index 00000000..b3c01cc8 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ALoadOperandInstruction.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class ALoadOperandInstruction extends VisitLocalVariableInstruction { + + public ALoadOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ANewArrayOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ANewArrayOperandInstruction.java new file mode 100644 index 00000000..8477db6f --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ANewArrayOperandInstruction.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.lang.reflect.Array; + +import static cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils.toFQClassName; + +public class ANewArrayOperandInstruction extends VisitTypeInstruction { + + public ANewArrayOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + Integer arraySize = (Integer) jobDetailsBuilder.getStack().pollLast(); + return Array.newInstance(ReflectionUtils.toClass(toFQClassName(type)), arraySize); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AStoreInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AStoreInstruction.java new file mode 100644 index 00000000..966f868e --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AStoreInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class AStoreInstruction extends StoreVariableInstruction { + + public AStoreInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AbstractJVMInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AbstractJVMInstruction.java new file mode 100644 index 00000000..2c01ca73 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AbstractJVMInstruction.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public abstract class AbstractJVMInstruction { + + public static final Object DO_NOT_PUT_ON_STACK = new Object(); + + protected final JobDetailsBuilder jobDetailsBuilder; + + protected AbstractJVMInstruction(JobDetailsBuilder jobDetailsBuilder) { + this.jobDetailsBuilder = jobDetailsBuilder; + } + + public abstract Object invokeInstruction(); + + public void invokeInstructionAndPushOnStack() { + Object result = invokeInstruction(); + if (result != DO_NOT_PUT_ON_STACK) { + jobDetailsBuilder.getStack().add(result); + } + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AllJVMInstructions.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AllJVMInstructions.java new file mode 100644 index 00000000..be9a74e3 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/AllJVMInstructions.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; +import org.objectweb.asm.Opcodes; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +import static java.util.Arrays.asList; + +public class AllJVMInstructions { + + private static final Map> instructions = new HashMap<>(); + private static final Map unsupportedInstructions = new HashMap<>(); + private static final Map kotlinUnsupportedInstructions = new HashMap<>(); + + static { + instructions.put(Opcodes.AASTORE, AAStoreInstruction::new); + instructions.put(Opcodes.ALOAD, ALoadOperandInstruction::new); + instructions.put(Opcodes.ANEWARRAY, ANewArrayOperandInstruction::new); + instructions.put(Opcodes.ASTORE, AStoreInstruction::new); + instructions.put(Opcodes.BIPUSH, SingleIntOperandInstruction::new); + instructions.put(Opcodes.CHECKCAST, CheckCastOperandInstruction::new); + instructions.put(Opcodes.DLOAD, DLoadOperandInstruction::new); + instructions.put(Opcodes.FLOAD, FLoadOperandInstruction::new); + instructions.put(Opcodes.I2B, I2BOperandInstruction::new); + instructions.put(Opcodes.I2C, I2COperandInstruction::new); + instructions.put(Opcodes.I2D, I2DOperandInstruction::new); + instructions.put(Opcodes.I2F, I2FOperandInstruction::new); + instructions.put(Opcodes.I2L, I2LOperandInstruction::new); + instructions.put(Opcodes.I2S, I2SOperandInstruction::new); + instructions.put(Opcodes.ICONST_0, IConst0OperandInstruction::new); + instructions.put(Opcodes.ICONST_1, IConst1OperandInstruction::new); + instructions.put(Opcodes.ICONST_2, IConst2OperandInstruction::new); + instructions.put(Opcodes.ICONST_3, IConst3OperandInstruction::new); + instructions.put(Opcodes.ICONST_4, IConst4OperandInstruction::new); + instructions.put(Opcodes.ICONST_5, IConst5OperandInstruction::new); + instructions.put(Opcodes.INVOKEDYNAMIC, InvokeDynamicInstruction::new); + instructions.put(Opcodes.INVOKEINTERFACE, InvokeInterfaceInstruction::new); + instructions.put(Opcodes.INVOKESPECIAL, InvokeSpecialInstruction::new); + instructions.put(Opcodes.INVOKESTATIC, InvokeStaticInstruction::new); + instructions.put(Opcodes.INVOKEVIRTUAL, InvokeVirtualInstruction::new); + instructions.put(Opcodes.ISTORE, IStoreInstruction::new); + instructions.put(Opcodes.LSTORE, LStoreInstruction::new); + instructions.put(Opcodes.DSTORE, DStoreInstruction::new); + instructions.put(Opcodes.FSTORE, FStoreInstruction::new); + instructions.put(Opcodes.DUP, DupOperandInstruction::new); + instructions.put(Opcodes.SWAP, SwapOperandInstruction::new); + instructions.put(Opcodes.ILOAD, ILoadOperandInstruction::new); + instructions.put(Opcodes.LCONST_0, LConst0OperandInstruction::new); + instructions.put(Opcodes.LCONST_1, LConst1OperandInstruction::new); + instructions.put(Opcodes.LDC, LdcInstruction::new); + instructions.put(Opcodes.LLOAD, LLoadOperandInstruction::new); + instructions.put(Opcodes.NEW, NewOperandInstruction::new); + instructions.put(Opcodes.POP, PopOperandInstruction::new); + instructions.put(Opcodes.GETFIELD, GetFieldInstruction::new); + instructions.put(Opcodes.GETSTATIC, GetStaticInstruction::new); + instructions.put(Opcodes.RETURN, ReturnOperandInstruction::new); + instructions.put(Opcodes.SIPUSH, SingleIntOperandInstruction::new); + // needed to support Jacoco + instructions.put(Opcodes.BASTORE, BAStoreOperandInstruction::new); + + String mathematicalPerformanceSuffix = " - for performance reasons it is better to do the calculation outside of the job lambda"; + asList(Opcodes.IADD, Opcodes.LADD, Opcodes.FADD, Opcodes.DADD) + .forEach(instr -> unsupportedInstructions.put(instr, "You are summing two numbers while enqueueing/scheduling jobs" + mathematicalPerformanceSuffix)); + asList(Opcodes.ISUB, Opcodes.LSUB, Opcodes.FSUB, Opcodes.DSUB) + .forEach(instr -> unsupportedInstructions.put(instr, "You are subtracting two numbers while enqueueing/scheduling jobs" + mathematicalPerformanceSuffix)); + asList(Opcodes.IMUL, Opcodes.LMUL, Opcodes.FMUL, Opcodes.DMUL) + .forEach(instr -> unsupportedInstructions.put(instr, "You are multiplying two numbers while enqueueing/scheduling jobs" + mathematicalPerformanceSuffix)); + asList(Opcodes.IDIV, Opcodes.LDIV, Opcodes.FDIV, Opcodes.DDIV) + .forEach(instr -> unsupportedInstructions.put(instr, "You are dividing two numbers while enqueueing/scheduling jobs" + mathematicalPerformanceSuffix)); + asList(Opcodes.IREM, Opcodes.LREM, Opcodes.FREM, Opcodes.DREM) + .forEach(instr -> unsupportedInstructions.put(instr, "You are calculating the remainder (%) for two numbers while enqueueing/scheduling jobs" + mathematicalPerformanceSuffix)); + + kotlinUnsupportedInstructions.put(Opcodes.ACONST_NULL, "You are (probably) using Kotlin default parameter values which is not supported by JobRunr."); + } + + private AllJVMInstructions() { + + } + + public static T get(int opcode, JobDetailsBuilder jobDetailsBuilder) { + final Function instructionBuilder = instructions.get(opcode); + if (instructionBuilder == null) { + if (unsupportedInstructions.containsKey(opcode)) { + throw new IllegalArgumentException("Unsupported lambda", new UnsupportedOperationException(unsupportedInstructions.get(opcode))); + } else if (ReflectionUtils.classExists("kotlin.KotlinVersion") && kotlinUnsupportedInstructions.containsKey(opcode)) { + throw new IllegalArgumentException("Unsupported lambda", new UnsupportedOperationException(kotlinUnsupportedInstructions.get(opcode))); + } + throw new IllegalArgumentException("Instruction " + opcode + " not found"); + } + return ReflectionUtils.cast(instructionBuilder.apply(jobDetailsBuilder)); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/BAStoreOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/BAStoreOperandInstruction.java new file mode 100644 index 00000000..01ba51ad --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/BAStoreOperandInstruction.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class BAStoreOperandInstruction extends ZeroOperandInstruction { + + public BAStoreOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load() { + // not needed + } + + @Override + public Object invokeInstruction() { + return null; + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/CheckCastOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/CheckCastOperandInstruction.java new file mode 100644 index 00000000..c582c8f0 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/CheckCastOperandInstruction.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class CheckCastOperandInstruction extends VisitTypeInstruction { + + public CheckCastOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load(String type) { + // not needed + } + + @Override + public Object invokeInstruction() { + return null; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DLoadOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DLoadOperandInstruction.java new file mode 100644 index 00000000..a59b1940 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DLoadOperandInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class DLoadOperandInstruction extends VisitLocalVariableInstruction { + + public DLoadOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DStoreInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DStoreInstruction.java new file mode 100644 index 00000000..5f92c7ab --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DStoreInstruction.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class DStoreInstruction extends StoreVariableInstruction { + + public DStoreInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + super.invokeInstruction(); + jobDetailsBuilder.addLocalVariable(null); //why: If the local variable at index is of type double or long, it occupies both index and index + 1. See https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html + return null; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DupOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DupOperandInstruction.java new file mode 100644 index 00000000..7480eb6d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/DupOperandInstruction.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class DupOperandInstruction extends ZeroOperandInstruction { + + public DupOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load() { + jobDetailsBuilder.pushInstructionOnStack(this); + } + + @Override + public Object invokeInstruction() { + if (jobDetailsBuilder.getStack().isEmpty()) return DO_NOT_PUT_ON_STACK; + return jobDetailsBuilder.getStack().getLast(); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/FLoadOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/FLoadOperandInstruction.java new file mode 100644 index 00000000..0198295e --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/FLoadOperandInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class FLoadOperandInstruction extends VisitLocalVariableInstruction { + + public FLoadOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/FStoreInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/FStoreInstruction.java new file mode 100644 index 00000000..c1c9de09 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/FStoreInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class FStoreInstruction extends StoreVariableInstruction { + + public FStoreInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/GetFieldInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/GetFieldInstruction.java new file mode 100644 index 00000000..1b5606f0 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/GetFieldInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils; + +public class GetFieldInstruction extends VisitFieldInstruction { + + public GetFieldInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return JobDetailsGeneratorUtils.getObjectViaField(jobDetailsBuilder.getStack().pollLast(), name); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/GetStaticInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/GetStaticInstruction.java new file mode 100644 index 00000000..a92d34b5 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/GetStaticInstruction.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils; + +public class GetStaticInstruction extends VisitFieldInstruction { + + public GetStaticInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + // TODO: how to know if we should invoke it or create JobDetails with static field? + String className = JobDetailsGeneratorUtils.toFQClassName(owner); + String methodName = name; + + if (className.equals(System.class.getName())) { + jobDetailsBuilder.setClassName(className); + jobDetailsBuilder.setStaticFieldName(name); + } + return JobDetailsGeneratorUtils.getObjectViaStaticField(className, methodName); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2BOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2BOperandInstruction.java new file mode 100644 index 00000000..ca5c0072 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2BOperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class I2BOperandInstruction extends ZeroOperandInstruction { + + public I2BOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + int intValue = (int) jobDetailsBuilder.getStack().pollLast(); + return (byte) intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2COperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2COperandInstruction.java new file mode 100644 index 00000000..175c7be2 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2COperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class I2COperandInstruction extends ZeroOperandInstruction { + + public I2COperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + int intValue = (int) jobDetailsBuilder.getStack().pollLast(); + return (char) intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2DOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2DOperandInstruction.java new file mode 100644 index 00000000..91cf06eb --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2DOperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class I2DOperandInstruction extends ZeroOperandInstruction { + + public I2DOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + int intValue = (int) jobDetailsBuilder.getStack().pollLast(); + return (double) intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2FOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2FOperandInstruction.java new file mode 100644 index 00000000..de0548fa --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2FOperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class I2FOperandInstruction extends ZeroOperandInstruction { + + public I2FOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + int intValue = (int) jobDetailsBuilder.getStack().pollLast(); + return (float) intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2LOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2LOperandInstruction.java new file mode 100644 index 00000000..de264cc8 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2LOperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class I2LOperandInstruction extends ZeroOperandInstruction { + + public I2LOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + int intValue = (int) jobDetailsBuilder.getStack().pollLast(); + return (long) intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2SOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2SOperandInstruction.java new file mode 100644 index 00000000..96ac38c3 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/I2SOperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class I2SOperandInstruction extends ZeroOperandInstruction { + + public I2SOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + int intValue = (int) jobDetailsBuilder.getStack().pollLast(); + return (short) intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst0OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst0OperandInstruction.java new file mode 100644 index 00000000..305af44e --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst0OperandInstruction.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IConst0OperandInstruction extends ZeroOperandInstruction { + + public IConst0OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 0; + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst1OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst1OperandInstruction.java new file mode 100644 index 00000000..132657d3 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst1OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IConst1OperandInstruction extends ZeroOperandInstruction { + + public IConst1OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 1; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst2OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst2OperandInstruction.java new file mode 100644 index 00000000..1e725a27 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst2OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IConst2OperandInstruction extends ZeroOperandInstruction { + + public IConst2OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 2; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst3OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst3OperandInstruction.java new file mode 100644 index 00000000..e9442e0b --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst3OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IConst3OperandInstruction extends ZeroOperandInstruction { + + public IConst3OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 3; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst4OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst4OperandInstruction.java new file mode 100644 index 00000000..59fb213b --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst4OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IConst4OperandInstruction extends ZeroOperandInstruction { + + public IConst4OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 4; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst5OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst5OperandInstruction.java new file mode 100644 index 00000000..7d28e127 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IConst5OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IConst5OperandInstruction extends ZeroOperandInstruction { + + public IConst5OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 5; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ILoadOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ILoadOperandInstruction.java new file mode 100644 index 00000000..d242a772 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ILoadOperandInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class ILoadOperandInstruction extends VisitLocalVariableInstruction { + + public ILoadOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IStoreInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IStoreInstruction.java new file mode 100644 index 00000000..e2512722 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/IStoreInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class IStoreInstruction extends StoreVariableInstruction { + + public IStoreInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeDynamicInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeDynamicInstruction.java new file mode 100644 index 00000000..d8a71e0d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeDynamicInstruction.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; +import org.objectweb.asm.Handle; + +import java.util.List; + +public class InvokeDynamicInstruction extends AbstractJVMInstruction { + + private String name; + private String descriptor; + private Handle bootstrapMethodHandle; + private Object[] bootstrapMethodArguments; + + public InvokeDynamicInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(String name, String descriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) { + jobDetailsBuilder.pushInstructionOnStack(this); + this.name = name; + this.descriptor = descriptor; + this.bootstrapMethodHandle = bootstrapMethodHandle; + this.bootstrapMethodArguments = bootstrapMethodArguments; + } + + public String getName() { + return name; + } + + public String getDescriptor() { + return descriptor; + } + + public Handle getBootstrapMethodHandle() { + return bootstrapMethodHandle; + } + + public Object[] getBootstrapMethodArguments() { + return bootstrapMethodArguments; + } + + @Override + public Object invokeInstruction() { + if ("makeConcatWithConstants".equals(name)) { + String result = bootstrapMethodArguments[0].toString(); + final List> paramTypes = JobDetailsGeneratorUtils.findParamTypesFromDescriptor(descriptor); + while (result.contains("\u0001") && !paramTypes.isEmpty()) { + final Class paramType = paramTypes.remove(paramTypes.size() - 1); + final Object value = ReflectionUtils.autobox(jobDetailsBuilder.getStack().pollLast(), paramType); + result = replaceLast(result, "\u0001", value.toString()); + } + return result; + } + throw new IllegalStateException("Unknown INVOKEDYNAMIC instruction: " + name); + } + + public static String replaceLast(String text, String regex, String replacement) { + return text.replaceFirst("(?s)" + regex + "(?!.*?" + regex + ")", replacement); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeInterfaceInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeInterfaceInstruction.java new file mode 100644 index 00000000..db9e5d8b --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeInterfaceInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class InvokeInterfaceInstruction extends JobDetailsInstruction { + + public InvokeInterfaceInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeSpecialInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeSpecialInstruction.java new file mode 100644 index 00000000..fd077cdf --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeSpecialInstruction.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.List; + +import static java.util.Arrays.stream; + +public class InvokeSpecialInstruction extends VisitMethodInstruction { + + public InvokeSpecialInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + if ("".equals(name)) { + String className = JobDetailsGeneratorUtils.toFQClassName(owner); + Class[] paramTypes = JobDetailsGeneratorUtils.findParamTypesFromDescriptorAsArray(descriptor); + List parameters = getParametersUsingParamTypes(paramTypes); + + Object objectViaConstructor = JobDetailsGeneratorUtils.createObjectViaConstructor(className, paramTypes, parameters.toArray()); + if (isKotlinMethodReference(objectViaConstructor)) { + jobDetailsBuilder.setClassName(((Class) ReflectionUtils.getValueFromFieldOrProperty(objectViaConstructor, "owner")).getName()); + jobDetailsBuilder.setMethodName((String) ReflectionUtils.getValueFromFieldOrProperty(objectViaConstructor, "name")); + } + return objectViaConstructor; + } + + String className = JobDetailsGeneratorUtils.toFQClassName(owner); + Class objectClass = ReflectionUtils.toClass(className); + Method method = ReflectionUtils.getMethod(objectClass, name, JobDetailsGeneratorUtils.findParamTypesFromDescriptorAsArray(descriptor)); + if (Modifier.isPrivate(method.getModifiers())) { + throw new RuntimeException(String.format("JobRunr cannot access member \"%s\" of class %s with modifiers \"private\". Please make the method \"public\".", name, className)); + } + + throw new IllegalStateException("Unknown INVOKESPECIAL instruction: " + className + "." + name); + } + + private boolean isKotlinMethodReference(Object objectViaConstructor) { + return stream(objectViaConstructor.getClass().getInterfaces()) + .map(Class::getName) + .anyMatch(name -> name.startsWith("kotlin.jvm.functions.Function")); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeStaticInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeStaticInstruction.java new file mode 100644 index 00000000..b76603f0 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeStaticInstruction.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils; + +import java.util.List; + +public class InvokeStaticInstruction extends JobDetailsInstruction { + + public InvokeStaticInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + if (isKotlinNullCheck()) { + getObject(); + return DO_NOT_PUT_ON_STACK; + } + return super.invokeInstruction(); + } + + protected Object getObject() { + Class[] paramTypes = JobDetailsGeneratorUtils.findParamTypesFromDescriptorAsArray(descriptor); + List parameters = getParametersUsingParamTypes(paramTypes); + if (isKotlinNullCheck()) return null; + Object result = JobDetailsGeneratorUtils.createObjectViaStaticMethod(getClassName(), getMethodName(), paramTypes, parameters.toArray()); + return result; + } + + private boolean isKotlinNullCheck() { + return getClassName().startsWith("kotlin.") && (getMethodName().startsWith("checkNotNull")); + } + + String getClassName() { + return JobDetailsGeneratorUtils.toFQClassName(owner); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeVirtualInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeVirtualInstruction.java new file mode 100644 index 00000000..d0f3b0ca --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/InvokeVirtualInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class InvokeVirtualInstruction extends JobDetailsInstruction { + + public InvokeVirtualInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/JobDetailsInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/JobDetailsInstruction.java new file mode 100644 index 00000000..55b97014 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/JobDetailsInstruction.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.reflection.JobDetailsGeneratorUtils; +import cn.sliew.carp.framework.common.reflection.JobParameter; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.Proxy; +import java.util.*; + +import static cn.sliew.carp.framework.common.util.reflection.ReflectionUtils.toClass; + +public class JobDetailsInstruction extends VisitMethodInstruction { + + public JobDetailsInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + if (!isLastJobDetailsInstruction() && isVoidInstruction()) { + throw new IllegalStateException("JobRunr only supports enqueueing/scheduling of one method"); + } else if (isLastJobDetailsInstruction()) { + jobDetailsBuilder.setClassName(getClassName()); + jobDetailsBuilder.setMethodName(getMethodName()); + jobDetailsBuilder.setJobParameters(getJobParameters()); + return null; + } else if (owner.startsWith("java")) { + return getObject(); + } else { + return getObject(); + } + } + + String getClassName() { + String className = JobDetailsGeneratorUtils.toFQClassName(owner); + if (jobDetailsBuilder.getStack().isEmpty()) { + return findInheritedClassName(className).orElse(className); + } + + ListIterator objectOnStackIterator = jobDetailsBuilder.getStack().listIterator(jobDetailsBuilder.getStack().size()); + while (objectOnStackIterator.hasPrevious()) { + Object jobOnStack = objectOnStackIterator.previous(); + if (jobOnStack != null && !jobOnStack.getClass().isSynthetic() && !Proxy.isProxyClass(jobOnStack.getClass())) { + Class jobClass = ReflectionUtils.toClass(className); + if (jobClass.isAssignableFrom(jobOnStack.getClass())) { + return jobOnStack.getClass().getName(); + } + } + } + return className; + } + + + String getMethodName() { + return name; + } + + protected Object getObject() { + Class[] paramTypes = JobDetailsGeneratorUtils.findParamTypesFromDescriptorAsArray(descriptor); + final Object ownerObject = jobDetailsBuilder.getStack().remove(jobDetailsBuilder.getStack().size() - 1 - paramTypes.length); + return JobDetailsGeneratorUtils.createObjectViaMethod(ownerObject, name, paramTypes, getParametersUsingParamTypes(paramTypes).toArray()); + } + + private Optional findInheritedClassName(String className) { + if (jobDetailsBuilder.getLocalVariable(0) != null && jobDetailsBuilder.getLocalVariable(0).getClass().getDeclaredFields().length > 0) { + final Field declaredField = jobDetailsBuilder.getLocalVariable(0).getClass().getDeclaredFields()[0]; + final Object valueFromField = ReflectionUtils.getValueFromField(declaredField, jobDetailsBuilder.getLocalVariable(0)); + if (toClass(className).isAssignableFrom(valueFromField.getClass())) { + return Optional.of(valueFromField.getClass().getName()); + } + } + return Optional.empty(); + } + + protected List getJobParameters() { + final List> paramTypesFromDescriptor = JobDetailsGeneratorUtils.findParamTypesFromDescriptor(descriptor); + final LinkedList> paramTypes = new LinkedList<>(paramTypesFromDescriptor); + + List result = new ArrayList<>(); + while (!paramTypes.isEmpty()) { + result.add(0, toJobParameter(paramTypes.pollLast(), jobDetailsBuilder.getStack().pollLast())); + } + return result; + } + + private JobParameter toJobParameter(Class paramType, Object param) { + if (param == null) { + throw new NullPointerException("You are passing null as a parameter to your background job for type " + paramType.getName() + " - JobRunr prevents this to fail fast."); + } + + if (ReflectionUtils.isClassAssignableToObject(paramType, param)) { + if (boolean.class.equals(paramType) && Integer.class.equals(param.getClass())) + return new JobParameter(paramType, ((Integer) param) > 0); + return new JobParameter(paramType, param); + } else { + throw new IllegalStateException("The found parameter types do not match the parameters."); + } + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LConst0OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LConst0OperandInstruction.java new file mode 100644 index 00000000..ab5302c0 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LConst0OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class LConst0OperandInstruction extends ZeroOperandInstruction { + + public LConst0OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 0L; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LConst1OperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LConst1OperandInstruction.java new file mode 100644 index 00000000..bdaed247 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LConst1OperandInstruction.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class LConst1OperandInstruction extends ZeroOperandInstruction { + + public LConst1OperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + return 1L; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LLoadOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LLoadOperandInstruction.java new file mode 100644 index 00000000..8d3a0a96 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LLoadOperandInstruction.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class LLoadOperandInstruction extends VisitLocalVariableInstruction { + + public LLoadOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LStoreInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LStoreInstruction.java new file mode 100644 index 00000000..b93538ea --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LStoreInstruction.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class LStoreInstruction extends StoreVariableInstruction { + + public LStoreInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public Object invokeInstruction() { + super.invokeInstruction(); + jobDetailsBuilder.addLocalVariable(null); //why: If the local variable at index is of type double or long, it occupies both index and index + 1. See https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html + return null; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LdcInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LdcInstruction.java new file mode 100644 index 00000000..f5e5f512 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/LdcInstruction.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class LdcInstruction extends AbstractJVMInstruction { + + private Object value; + + public LdcInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(Object value) { + this.value = value; + jobDetailsBuilder.pushInstructionOnStack(this); + } + + @Override + public Object invokeInstruction() { + return value; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/NewOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/NewOperandInstruction.java new file mode 100644 index 00000000..fc58bfa0 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/NewOperandInstruction.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class NewOperandInstruction extends VisitTypeInstruction { + + public NewOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load(String type) { + // not needed + } + + @Override + public Object invokeInstruction() { + return null; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/PopOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/PopOperandInstruction.java new file mode 100644 index 00000000..9f8a4383 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/PopOperandInstruction.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class PopOperandInstruction extends ZeroOperandInstruction { + + public PopOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load() { + // not needed + } + + @Override + public Object invokeInstruction() { + return null; + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ReturnOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ReturnOperandInstruction.java new file mode 100644 index 00000000..a8a685d8 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ReturnOperandInstruction.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class ReturnOperandInstruction extends ZeroOperandInstruction { + + public ReturnOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load() { + // not needed + } + + @Override + public Object invokeInstruction() { + return null; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/SingleIntOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/SingleIntOperandInstruction.java new file mode 100644 index 00000000..9076f6ef --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/SingleIntOperandInstruction.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class SingleIntOperandInstruction extends AbstractJVMInstruction { + + private int intValue; + + public SingleIntOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(int intValue) { + this.intValue = intValue; + jobDetailsBuilder.pushInstructionOnStack(this); + } + + @Override + public Object invokeInstruction() { + return intValue; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/StoreVariableInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/StoreVariableInstruction.java new file mode 100644 index 00000000..7684e29c --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/StoreVariableInstruction.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public class StoreVariableInstruction extends VisitLocalVariableInstruction { + + public StoreVariableInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public int getVariable() { + return variable; + } + + @Override + public void invokeInstructionAndPushOnStack() { + invokeInstruction(); // nothing to put on the stack + } + + @Override + public Object invokeInstruction() { + jobDetailsBuilder.addLocalVariable(jobDetailsBuilder.getStack().pollLast()); + return null; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/SwapOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/SwapOperandInstruction.java new file mode 100644 index 00000000..dab914c6 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/SwapOperandInstruction.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +import java.util.LinkedList; + +public class SwapOperandInstruction extends ZeroOperandInstruction { + + public SwapOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + @Override + public void load() { + jobDetailsBuilder.pushInstructionOnStack(this); + } + + @Override + public Object invokeInstruction() { + LinkedList stack = jobDetailsBuilder.getStack(); + Object el1 = stack.get(0); + Object el2 = stack.get(1); + stack.set(0, el2); + stack.set(1, el1); + return DO_NOT_PUT_ON_STACK; + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitFieldInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitFieldInstruction.java new file mode 100644 index 00000000..0cd2fdaa --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitFieldInstruction.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public abstract class VisitFieldInstruction extends AbstractJVMInstruction { + + protected String owner; + protected String name; + protected String descriptor; + + protected VisitFieldInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(String owner, String name, String descriptor) { + this.owner = owner; + this.name = name; + this.descriptor = descriptor; + jobDetailsBuilder.pushInstructionOnStack(this); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitLocalVariableInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitLocalVariableInstruction.java new file mode 100644 index 00000000..766a9e3b --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitLocalVariableInstruction.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public abstract class VisitLocalVariableInstruction extends AbstractJVMInstruction { + + protected int variable; + + protected VisitLocalVariableInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(int variable) { + this.variable = variable; + jobDetailsBuilder.pushInstructionOnStack(this); + } + + @Override + public Object invokeInstruction() { + return jobDetailsBuilder.getLocalVariable(variable); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitMethodInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitMethodInstruction.java new file mode 100644 index 00000000..5af0d522 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitMethodInstruction.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +public abstract class VisitMethodInstruction extends AbstractJVMInstruction { + + protected String owner; + protected String name; + protected String descriptor; + protected boolean isInterface; + + protected VisitMethodInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(String owner, String name, String descriptor, boolean isInterface) { + this.owner = owner; + this.name = name; + this.descriptor = descriptor; + this.isInterface = isInterface; + jobDetailsBuilder.pushInstructionOnStack(this); + } + + protected boolean isVoidInstruction() { + return descriptor.endsWith(")V"); + } + + protected boolean isLastJobDetailsInstruction() { + return jobDetailsBuilder.getInstructions().stream().noneMatch(JobDetailsInstruction.class::isInstance); + } + + protected List getParametersUsingParamTypes(Class[] paramTypesAsArray) { + LinkedList> paramTypes = new LinkedList<>(Arrays.asList(paramTypesAsArray)); + List result = new ArrayList<>(); + while (!paramTypes.isEmpty()) { + Class paramType = paramTypes.pollLast(); + result.add(0, ReflectionUtils.autobox(jobDetailsBuilder.getStack().pollLast(), paramType)); + } + return result; + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitTypeInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitTypeInstruction.java new file mode 100644 index 00000000..c69974bf --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/VisitTypeInstruction.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public abstract class VisitTypeInstruction extends AbstractJVMInstruction { + + protected String type; + + protected VisitTypeInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load(String type) { + this.type = type; + jobDetailsBuilder.pushInstructionOnStack(this); + } + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ZeroOperandInstruction.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ZeroOperandInstruction.java new file mode 100644 index 00000000..bb1f8696 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/instructions/ZeroOperandInstruction.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.instructions; + +import cn.sliew.carp.framework.common.reflection.JobDetailsBuilder; + +public abstract class ZeroOperandInstruction extends AbstractJVMInstruction { + + protected ZeroOperandInstruction(JobDetailsBuilder jobDetailsBuilder) { + super(jobDetailsBuilder); + } + + public void load() { + jobDetailsBuilder.pushInstructionOnStack(this); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/IocJobLambda.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/IocJobLambda.java new file mode 100644 index 00000000..96e4da8d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/IocJobLambda.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.lambdas; + +/** + * This is a functional interface which represents a lambda that will be parsed by JobRunr. + * You may not create an actual instance of this class, instead you use it as follows: + * + *
{@code
+ *     BackgroundJob.enqueue(x -> x.doWork("some argument"))
+ * }
+ *

+ * or + *

{@code
+ *     jobScheduler.enqueue(x -> x.doWork("some argument"))
+ * }
+ *

+ * This functional interface allows you to enqueue background jobs without having an actual instance available of your service. + * While processing, JobRunr will lookup the actual service in the IoC container or create a new instance using the default constructor. + * + * @param Your service on which you want to call a background job method. + */ +@FunctionalInterface +public interface IocJobLambda extends JobRunrJob { + + void accept(S service) throws Exception; +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/JobLambda.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/JobLambda.java new file mode 100644 index 00000000..d79f29ad --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/JobLambda.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.lambdas; + +/** + * This is a functional interface which represents a lambda that will be parsed by JobRunr. + * You may not create an actual instance of this class, instead you use it as follows: + * + *

{@code
+ *
+ *     @Inject
+ *     MyService myService;
+ *
+ *     BackgroundJob.enqueue(myService -> myService.doWork("some argument"))
+ * }
+ *

+ * or + *

{@code
+ *
+ *     @Inject
+ *     MyService myService;
+ *
+ *     jobScheduler.enqueue(myService -> myService.doWork("some argument"))
+ * }
+ *

+ * This functional interface allows you to enqueue background jobs while having an actual instance available of your service. + * While processing, JobRunr will lookup the actual service in the IoC container or create a new instance using the default constructor. + */ +@FunctionalInterface +public interface JobLambda extends JobRunrJob { + + void run() throws Exception; +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/JobRunrJob.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/JobRunrJob.java new file mode 100644 index 00000000..6cc0ea9e --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/lambdas/JobRunrJob.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.lambdas; + +import java.io.Serializable; + +public interface JobRunrJob extends Serializable { + // marker interface to make it serializable +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/package-info.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/package-info.java new file mode 100644 index 00000000..f4f4841d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/package-info.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * lambda instructions copied from jobrunr project + */ +package cn.sliew.carp.framework.common.reflection; \ No newline at end of file diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/postprocess/CGLibPostProcessor.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/postprocess/CGLibPostProcessor.java new file mode 100644 index 00000000..952696ea --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/postprocess/CGLibPostProcessor.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.postprocess; + +import cn.sliew.carp.framework.common.reflection.JobDetails; +import org.apache.commons.lang3.StringUtils; + +public class CGLibPostProcessor implements JobDetailsPostProcessor { + + @Override + public JobDetails postProcess(JobDetails jobDetails) { + if (StringUtils.isNotBlank(StringUtils.substringBetween(jobDetails.getClassName(), "$$", "$$"))) { + return new JobDetails( + StringUtils.substringBefore(jobDetails.getClassName(), "$$"), + jobDetails.getStaticFieldName(), + jobDetails.getMethodName(), + jobDetails.getJobParameters() + ); + } + return jobDetails; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/postprocess/JobDetailsPostProcessor.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/postprocess/JobDetailsPostProcessor.java new file mode 100644 index 00000000..488d144c --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/reflection/postprocess/JobDetailsPostProcessor.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.reflection.postprocess; + +import cn.sliew.carp.framework.common.reflection.JobDetails; + +public interface JobDetailsPostProcessor { + + JobDetails postProcess(JobDetails jobDetails); + +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/Message.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/Message.java new file mode 100644 index 00000000..52aea179 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/Message.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.rpc.message; + +import cn.sliew.carp.framework.common.jackson.polymorphic.Polymorphic; +import com.fasterxml.jackson.annotation.JsonSubTypes; + +@JsonSubTypes({ + @JsonSubTypes.Type(name = RpcMethodMessage.TYPE, value = RpcMethodMessage.class) +}) +public interface Message extends Polymorphic { + + @Override + String getType(); +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/RpcLambdaMessage.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/RpcLambdaMessage.java new file mode 100644 index 00000000..72a3ed97 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/RpcLambdaMessage.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.rpc.message; + +import lombok.Data; + +@Data +public class RpcLambdaMessage extends RpcMethodMessage { + + public static final String TYPE = "rpc-lambda"; + + private String staticFieldName; + + @Override + public String getType() { + return TYPE; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/RpcMethodMessage.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/RpcMethodMessage.java new file mode 100644 index 00000000..51e759ae --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/rpc/message/RpcMethodMessage.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.rpc.message; + +import lombok.Data; + +/** + * dubbo: InvokerInvocationHandler + */ +@Data +public class RpcMethodMessage implements Message { + + public static final String TYPE = "rpc-method"; + + private String className; + private String method; + private Class[] paramTypes; + private Object[] params; + + @Override + public String getType() { + return TYPE; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/AbstractSerDerFactory.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/AbstractSerDerFactory.java new file mode 100644 index 00000000..53749710 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/AbstractSerDerFactory.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.serder; + +public abstract class AbstractSerDerFactory implements SerDerFactory { + + private SerDer serDer; + + @Override + public SerDer getInstance() { + if (serDer != null) { + return serDer; + } + synchronized (AbstractSerDerFactory.class) { + if (serDer != null) { + return serDer; + } + serDer = create(); + return serDer; + } + } + + protected abstract SerDer create(); +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/SerDer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/SerDer.java new file mode 100644 index 00000000..ef4e43c7 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/SerDer.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.serder; + +public interface SerDer { + + byte[] serialize(Object object); + + T deserialize(byte[] bytes, Class clazz); +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/SerDerFactory.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/SerDerFactory.java new file mode 100644 index 00000000..86e52b57 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/SerDerFactory.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.serder; + +public interface SerDerFactory { + + SerDer getInstance(); +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jackson/JacksonSerDer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jackson/JacksonSerDer.java new file mode 100644 index 00000000..06ab0725 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jackson/JacksonSerDer.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.serder.jackson; + +import cn.sliew.carp.framework.common.serder.SerDer; +import cn.sliew.milky.common.util.JacksonUtil; + +import java.nio.charset.StandardCharsets; + +public class JacksonSerDer implements SerDer { + + @Override + public byte[] serialize(Object object) { + return JacksonUtil.toJsonString(object).getBytes(StandardCharsets.UTF_8); + } + + @Override + public T deserialize(byte[] bytes, Class clazz) { + return JacksonUtil.parseJsonString(new String(bytes, StandardCharsets.UTF_8), clazz); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jackson/JacksonSerDerFactory.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jackson/JacksonSerDerFactory.java new file mode 100644 index 00000000..19895e0a --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jackson/JacksonSerDerFactory.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.serder.jackson; + +import cn.sliew.carp.framework.common.serder.AbstractSerDerFactory; +import cn.sliew.carp.framework.common.serder.SerDer; +import cn.sliew.carp.framework.common.serder.jdk.JdkSerDerFactory; + +public class JacksonSerDerFactory extends AbstractSerDerFactory { + + public static final JdkSerDerFactory INSTANCE = new JdkSerDerFactory(); + + @Override + protected SerDer create() { + return new JacksonSerDer(); + } +} diff --git a/carp-modules/carp-module-queue/carp-module-queue-api/src/main/java/cn/sliew/carp/module/queue/api/util/Serder.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jdk/JdkSerDer.java similarity index 79% rename from carp-modules/carp-module-queue/carp-module-queue-api/src/main/java/cn/sliew/carp/module/queue/api/util/Serder.java rename to carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jdk/JdkSerDer.java index dbd66c23..be570091 100644 --- a/carp-modules/carp-module-queue/carp-module-queue-api/src/main/java/cn/sliew/carp/module/queue/api/util/Serder.java +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jdk/JdkSerDer.java @@ -16,28 +16,30 @@ * limitations under the License. */ -package cn.sliew.carp.module.queue.api.util; +package cn.sliew.carp.framework.common.serder.jdk; + +import cn.sliew.carp.framework.common.serder.SerDer; import java.io.*; -public enum Serder { - ; +public class JdkSerDer implements SerDer { - public static byte[] serializeByJava(Object obj) { + @Override + public byte[] serialize(Object object) { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos)) { - oos.writeObject(obj); + oos.writeObject(object); return bos.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } } - public static Object deserializeByJava(byte[] bytes) { + @Override + public T deserialize(byte[] bytes, Class clazz) { try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); ObjectInputStream ois = new ObjectInputStream(bis)) { - return ois.readObject(); - + return (T) ois.readObject(); } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jdk/JdkSerDerFactory.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jdk/JdkSerDerFactory.java new file mode 100644 index 00000000..e13c71ba --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/serder/jdk/JdkSerDerFactory.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.serder.jdk; + +import cn.sliew.carp.framework.common.serder.AbstractSerDerFactory; +import cn.sliew.carp.framework.common.serder.SerDer; + +public class JdkSerDerFactory extends AbstractSerDerFactory { + + public static final JdkSerDerFactory INSTANCE = new JdkSerDerFactory(); + + @Override + protected SerDer create() { + return new JdkSerDer(); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/Test.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/Test.java new file mode 100644 index 00000000..b6472096 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/Test.java @@ -0,0 +1,30 @@ +package cn.sliew.carp.framework.common.util; + +import cn.hutool.core.codec.Base64; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; + +import java.security.KeyPair; + +public class Test { + + private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIM2r5hz37QIlsSNN0UNaya8REFxlPoEoc6kN69KEqjKnFG0SFeyTgcHsTlz7NDNgZKuL5R3NT/T/RkFZJZzynlwc+Dim5eeKTGp4EptjthsvKVDJ6N6+p3IatJR0OsHIWKnQlfgzCkni49VQo5vGVM7sk0QQb3SBxRyAMv1WIZPAgMBAAECgYASHYKwsY649FacXEK9LdUVS/jAcEX5HpqYROPLN5bL5u0d+p3iPaO4JL+7Bt4zFaxF6/Z1sN+RKFtREQWKIAJb/rYrB/gJ1auN7dIXao1Xcq3pJvqYNqoV9JbGN1wwgyojFri2eTdPCrLeuIwCxYUJoHmZE8ODdXPCE+ZAtyMLQQJBANEflTbmJhuaAS5LFVmEdCclwRncZtOspS9ODn99Zd69HGtiCw+YqMnnIKDTwI3ep1qs8/MvqaLuDFg4TDY3aOsCQQCgoEyg+8ll4xATdkaaIWwxhOa9OD8blSPePbt/3gyISddMhLVV53Dq1GDNBwrzV6sLQb0781FFTVTXrhyuC/8tAkEAq/SdXJwYn7+d0vQYZRhd7kbEJsCtqMaguWokz75MAsBb2wyuba+oswSjNruH7OA1moD2w3PguEGn0u7P9BDR6wJAOs10QBrtB9ewMu/BuPszWI2Gyw6kS7y1fM6srYrkm6AsqV6L4/7uX4mQRn6li6A0hdJzLFdPEUfWH38mELFjoQJALbHs/5FmwxQFp04ZtlI74AKIUCnzvBdt+9EBIhhj/Hi3fNyOiNBNi/unONvCYq89zMxsypOIFvMynKHwJWRrZg=="; + private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCDNq+Yc9+0CJbEjTdFDWsmvERBcZT6BKHOpDevShKoypxRtEhXsk4HB7E5c+zQzYGSri+UdzU/0/0ZBWSWc8p5cHPg4puXnikxqeBKbY7YbLylQyejevqdyGrSUdDrByFip0JX4MwpJ4uPVUKObxlTO7JNEEG90gcUcgDL9ViGTwIDAQAB"; + + public static void main(String[] args) { + String text = "1000000000000000000000000000000000000000000000000000000"; + RSA rsa = SecureUtil.rsa(PRIVATE_KEY, PUBLIC_KEY); + String encrypted = rsa.encryptBase64(text, KeyType.PublicKey); + System.out.println("长度: " + encrypted.length() + ", 密文: " + encrypted); + String decrypted = rsa.decryptStr(encrypted, KeyType.PrivateKey); + System.out.println(decrypted); + } + + + private static void generateKeyPair() { + KeyPair rsa = SecureUtil.generateKeyPair("rsa"); + System.out.println(Base64.encode(rsa.getPrivate().getEncoded())); + System.out.println(Base64.encode(rsa.getPublic().getEncoded())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/JarUtils.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/JarUtils.java new file mode 100644 index 00000000..48a0727d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/JarUtils.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection; + +import java.io.InputStream; +import java.net.URL; +import java.util.jar.Manifest; + +public enum JarUtils { + ; + + public static String getVersion(Class clazz) { + String version = clazz.getPackage().getImplementationVersion(); + if (version != null) return version; + + return getManifestAttributeValue(clazz, "Bundle-Version"); + } + + public static String getManifestAttributeValue(Class clazz, String attributeName) { + return getManifest(clazz).getMainAttributes().getValue(attributeName); + } + + private static Manifest getManifest(Class clazz) { + String resource = "/" + clazz.getName().replace(".", "/") + ".class"; + String fullPath = clazz.getResource(resource).toString(); + String archivePath = fullPath.substring(0, fullPath.length() - resource.length()); + if (archivePath.endsWith("\\WEB-INF\\classes") || archivePath.endsWith("/WEB-INF/classes")) { + archivePath = archivePath.substring(0, archivePath.length() - "/WEB-INF/classes".length()); // Required for wars + } + + try (InputStream input = new URL(archivePath + "/META-INF/MANIFEST.MF").openStream()) { + return new Manifest(input); + } catch (Exception e) { + throw new RuntimeException("Loading MANIFEST for class " + clazz + " failed!", e); + } + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/MethodFinderPredicate.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/MethodFinderPredicate.java new file mode 100644 index 00000000..48e4e11d --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/MethodFinderPredicate.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.function.Predicate; + +public class MethodFinderPredicate implements Predicate { + + private final String methodName; + private final Class[] parameterTypes; + + public MethodFinderPredicate(String methodName, Class... parameterTypes) { + this.methodName = methodName; + this.parameterTypes = parameterTypes; + } + + @Override + public boolean test(Method method) { + if(method.isBridge()) return false; // method generated by compiler with same signature. + + return methodName.equals(method.getName()) && ( + Arrays.equals(method.getParameterTypes(), parameterTypes) + || compareParameterTypesForPrimitives(method.getParameterTypes())); + } + + private boolean compareParameterTypesForPrimitives(Class[] parameterTypes) { + if (this.parameterTypes.length != parameterTypes.length) return false; + + boolean result = true; + for (int i = 0; i < parameterTypes.length; i++) { + result &= ReflectionUtils.isClassAssignable(parameterTypes[i], this.parameterTypes[i]); + } + return result; + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/ReflectionUtils.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/ReflectionUtils.java new file mode 100644 index 00000000..ebc96e73 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/ReflectionUtils.java @@ -0,0 +1,346 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection; + +import cn.sliew.carp.framework.common.util.reflection.autobox.Autoboxer; +import cn.sliew.milky.common.exception.Rethrower; +import cn.sliew.milky.common.primitives.Strings; + +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import static java.lang.Thread.currentThread; +import static java.util.Arrays.stream; + +public enum ReflectionUtils { + ; + + private static final String ROOT_PACKAGE_NAME = "org/jobrunr/"; + private static final Map, Class> PRIMITIVE_TO_TYPE_MAPPING = new HashMap<>(); + + static { + PRIMITIVE_TO_TYPE_MAPPING.put(boolean.class, Boolean.class); + PRIMITIVE_TO_TYPE_MAPPING.put(byte.class, Byte.class); + PRIMITIVE_TO_TYPE_MAPPING.put(short.class, Short.class); + PRIMITIVE_TO_TYPE_MAPPING.put(char.class, Character.class); + PRIMITIVE_TO_TYPE_MAPPING.put(int.class, Integer.class); + PRIMITIVE_TO_TYPE_MAPPING.put(long.class, Long.class); + PRIMITIVE_TO_TYPE_MAPPING.put(float.class, Float.class); + PRIMITIVE_TO_TYPE_MAPPING.put(double.class, Double.class); + } + + public static boolean classExists(String className) { + try { + loadClass(className); + return true; + } catch (ClassNotFoundException e) { + return false; + } + } + + public static Class toClassFromPath(Path path) { + final String classFile = path.toString().substring(path.toString().indexOf(ROOT_PACKAGE_NAME)); + String className = toClassNameFromFileName(classFile); + return toClass(className); + } + + public static String toClassNameFromFileName(String classFile) { + return classFile.replace(".class", "").replace("/", "."); + } + + public static Class toClass(String className) { + switch (className) { + case "boolean": + return cast(boolean.class); + case "byte": + return cast(byte.class); + case "short": + return cast(short.class); + case "int": + return cast(int.class); + case "long": + return cast(long.class); + case "float": + return cast(float.class); + case "double": + return cast(double.class); + case "char": + return cast(char.class); + case "void": + return cast(void.class); + default: + try { + return cast(loadClass(className)); + } catch (ClassNotFoundException ex) { + throw new IllegalArgumentException("Class not found: " + className, ex); + } + } + } + + public static Class loadClass(String className) throws ClassNotFoundException { + // why: support for quarkus:dev (see https://github.com/quarkusio/quarkus/issues/2809) and Spring Boot Live reload + // Jackson uses this order also + try { + ClassLoader classLoader = currentThread().getContextClassLoader(); + if (classLoader != null) { + return Class.forName(className, true, classLoader); + } + } catch (ClassNotFoundException e) { + // support for Spring Boot Executable jar. See https://github.com/jobrunr/jobrunr/issues/81 + } + return Class.forName(className); + } + + public static boolean hasDefaultNoArgConstructor(String clazzName) { + return Stream.of(toClass(clazzName).getConstructors()) + .anyMatch(c -> c.getParameterCount() == 0); + } + + public static boolean hasDefaultNoArgConstructor(Class clazz) { + return Stream.of(clazz.getConstructors()) + .anyMatch(c -> c.getParameterCount() == 0); + } + + public static T newInstanceAndSetFieldValues(Class clazz, Map fieldValues) { + T t = newInstance(clazz); + fieldValues.forEach((key, value) -> findField(clazz, key) + .ifPresent(f -> setFieldUsingAutoboxing(f, t, value))); + return t; + } + + public static T newInstance(String className, Object... params) { + return newInstance(toClass(className), params); + } + + public static T newInstance(Class clazz, Object... params) { + try { + return newInstanceCE(clazz, params); + } catch (ReflectiveOperationException e) { + Rethrower.throwAs(e); + return null; + } + } + + public static T newInstanceCE(Class clazz, Object... params) throws ReflectiveOperationException { + final Constructor declaredConstructor = getConstructorForArgs(clazz, Stream.of(params).map(Object::getClass).toArray(Class[]::new)); + makeAccessible(declaredConstructor); + return declaredConstructor.newInstance(params); + } + + public static T newInstanceCE(Class clazz) throws ReflectiveOperationException { + Constructor defaultConstructor = clazz.getDeclaredConstructor(); + makeAccessible(defaultConstructor); + return defaultConstructor.newInstance(); + } + + public static T newInstance(Class clazz) { + try { + Constructor defaultConstructor = clazz.getDeclaredConstructor(); + makeAccessible(defaultConstructor); + return defaultConstructor.newInstance(); + } catch (ReflectiveOperationException e) { + Rethrower.throwAs(e); + return null; + } + } + + public static Method getMethod(Class clazz, String methodName, Class... parameterTypes) { + return findMethod(clazz, methodName, parameterTypes) + .orElseThrow(() -> new RuntimeException()); + } + + public static Optional findMethod(Object object, String methodName, Class... parameterTypes) { + return findMethod(object.getClass(), new MethodFinderPredicate(methodName, parameterTypes)); + } + + public static Optional findMethod(Class clazz, String methodName, Class... parameterTypes) { + return findMethod(clazz, new MethodFinderPredicate(methodName, parameterTypes)); + } + + public static Optional findMethod(Class clazz, Predicate predicate) { + final Optional optionalMethod = stream(clazz.getDeclaredMethods()) + .filter(predicate) + .findFirst(); + if (optionalMethod.isPresent()) { + return optionalMethod; + } else if (clazz.isInterface()) { + return Stream.of(clazz.getInterfaces()) + .map(superInterface -> findMethod(superInterface, predicate)) + .filter(Optional::isPresent) + .findFirst() + .orElse(Optional.empty()); + } else if (!Object.class.equals(clazz.getSuperclass())) { + return findMethod(clazz.getSuperclass(), predicate); + } else { + return Optional.empty(); + } + } + + public static Field getField(Class clazz, String fieldName) { + return findField(clazz, fieldName) + .orElseThrow(() -> new RuntimeException()); + } + + public static Optional findField(Class clazz, String fieldName) { + return findField(clazz, f -> fieldName.equals(f.getName())); + } + + public static Optional findField(Class clazz, Predicate predicate) { + final Optional optionalField = stream(clazz.getDeclaredFields()) + .filter(predicate) + .findFirst(); + if (optionalField.isPresent()) { + return optionalField; + } else if (!Object.class.equals(clazz.getSuperclass())) { + return findField(clazz.getSuperclass(), predicate); + } else { + return Optional.empty(); + } + } + + public static boolean isClassAssignableToObject(Class clazz, Object object) { + return isClassAssignable(clazz, object.getClass()); + } + + public static boolean isClassAssignable(Class clazz1, Class clazz2) { + return clazz1.equals(clazz2) + || clazz1.isAssignableFrom(clazz2) + || (clazz1.isPrimitive() && PRIMITIVE_TO_TYPE_MAPPING.get(clazz1).equals(clazz2)) + || (clazz1.isPrimitive() && Boolean.TYPE.equals(clazz1) && Integer.class.equals(clazz2)); + } + + public static boolean objectContainsFieldOrProperty(Object object, String fieldName) { + if (object == null) return false; + return objectContainsField(object, fieldName) || objectContainsProperty(object, fieldName); + } + + public static Object getValueFromFieldOrProperty(Object object, String paramName) { + Class aClass = object.getClass(); + final Optional optionalField = findField(aClass, paramName); + if (optionalField.isPresent()) { + return getValueFromField(optionalField.get(), object); + } + + final Optional optionalGetMethod = findMethod(aClass, "get" + Strings.capitalize(paramName)); + if (optionalGetMethod.isPresent()) { + return getValueFromGetMethod(optionalGetMethod.get(), object); + } + + throw new IllegalArgumentException(String.format("Could not get value '%s' from object with class %s", paramName, object.getClass())); + } + + public static Object getValueFromField(Field field, Object object) { + try { + makeAccessible(field); + return field.get(object); + } catch (ReflectiveOperationException willNotHappen) { + throw new IllegalArgumentException(String.format("Could not get value '%s' from object with class %s", field.getName(), object.getClass())); + } + } + + public static Object getValueFromGetMethod(Method getter, Object object) { + try { + makeAccessible(getter); + return getter.invoke(object); + } catch (ReflectiveOperationException willNotHappen) { + throw new IllegalArgumentException(String.format("Could not get value '%s' from object with class %s", getter.getName(), object.getClass())); + } + } + + public static void setFieldUsingAutoboxing(String fieldName, Object object, Object value) { + if (value == null) return; + + setFieldUsingAutoboxing(getField(object.getClass(), fieldName), object, value); + } + + public static void setFieldUsingAutoboxing(Field field, Object object, Object value) { + try { + if (value == null) return; + + makeAccessible(field); + final Class type = field.getType(); + + Object fieldValue = autobox(value, type); + field.set(object, fieldValue); + } catch (ReflectiveOperationException e) { + Rethrower.throwAs(e); + } + } + + public static T autobox(Object value, Class type) { + return Autoboxer.autobox(value, type); + } + + public static void makeAccessible(AccessibleObject accessibleObject) { + accessibleObject.setAccessible(true); + } + + private static Constructor getConstructorForArgs(Class clazz, Class[] args) throws NoSuchMethodException { + Constructor[] constructors = clazz.getConstructors(); + + for (Constructor constructor : constructors) { + Class[] types = constructor.getParameterTypes(); + if (types.length == args.length) { + boolean argumentsMatch = true; + for (int i = 0; i < args.length; i++) { + if (!types[i].isAssignableFrom(args[i])) { + argumentsMatch = false; + break; + } + } + + if (argumentsMatch) return cast(constructor); + } + } + + return clazz.getConstructor(args); + } + + /** + * Why: less warnings and @SuppressWarnings("unchecked") + */ + @SuppressWarnings("unchecked") + private static Class cast(Class aClass) { + return (Class) aClass; + } + + /** + * Why: less warnings and @SuppressWarnings("unchecked") + */ + @SuppressWarnings("unchecked") + public static T cast(Object anObject) { + return (T) anObject; + } + + private static boolean objectContainsField(Object object, String fieldName) { + return findField(object.getClass(), fieldName).isPresent(); + } + + private static boolean objectContainsProperty(Object object, String fieldName) { + return findMethod(object.getClass(), "get" + Strings.capitalize(fieldName)).isPresent(); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/SerializedLambdaUtil.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/SerializedLambdaUtil.java new file mode 100644 index 00000000..8e84beb2 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/SerializedLambdaUtil.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection; + +import cn.sliew.carp.framework.common.reflection.JobDetails; +import cn.sliew.carp.framework.common.reflection.JobDetailsAsmGenerator; +import cn.sliew.carp.framework.common.reflection.JobDetailsGenerator; +import cn.sliew.carp.framework.common.reflection.lambdas.JobLambda; +import cn.sliew.milky.common.exception.Rethrower; +import cn.sliew.milky.common.util.JacksonUtil; + +import java.io.InputStream; +import java.io.Serializable; +import java.lang.invoke.SerializedLambda; +import java.lang.reflect.Method; + +public enum SerializedLambdaUtil { + ; + + public static SerializedLambda toSerializedLambda(T value) { + if (!value.getClass().isSynthetic()) { + throw new IllegalArgumentException("support lambda expression only"); + } + + if (!(value instanceof Serializable)) { + throw new RuntimeException("lambda must be Serializable"); + } + + try { + Method writeReplaceMethod = value.getClass().getDeclaredMethod("writeReplace"); + ReflectionUtils.makeAccessible(writeReplaceMethod); + return (SerializedLambda) writeReplaceMethod.invoke(value); + } catch (Exception ignored) { + Rethrower.throwAs(ignored); + return null; + } + } + + public static String toFQClassName(String byteCodeName) { + return byteCodeName.replace("/", "."); + } + + public static String toFQResource(String byteCodeName) { + return byteCodeName.replace(".", "/"); + } + + public static InputStream getLambdaDeclaringClassAsInputStream(SerializedLambda lambda) { + String location = getClassLocationOfLambda(lambda); + return lambda.getClass().getResourceAsStream(location); + } + + public static String getClassLocationOfLambda(SerializedLambda lambda) { + String name = lambda.getImplClass(); + return "/" + toFQResource(name.substring(0, name.indexOf("$$"))) + ".class"; + } + + public static SerializedLambda testLambda(JobLambda invocation) { + return toSerializedLambda(invocation); + } + + public static JobDetails testJobDetails(JobLambda invocation) { + JobDetailsGenerator generator = new JobDetailsAsmGenerator(); + return generator.toJobDetails(invocation); + } + + public static void main(String[] args) { + testJobDetails(); +// testSerializedLambda(); + } + + private static void testJobDetails() { + String echo = "hello, lambda"; + JobDetails jobDetails = testJobDetails(() -> System.out.println(echo)); + System.out.println(JacksonUtil.toJsonString(jobDetails)); + } + + private static void testSerializedLambda() { + String echo = "hello, lambda"; + SerializedLambda serializedLambda = testLambda(() -> System.out.println(echo)); + + // cn/sliew/carp/framework/common/util/reflection/SerializedLambdaUtil + System.out.println(serializedLambda.getImplClass()); + // lambda$main$d04c9b6f$1 + System.out.println(serializedLambda.getImplMethodName()); + // 6 + System.out.println(serializedLambda.getImplMethodKind()); + // string -> void + System.out.println(serializedLambda.getImplMethodSignature()); + + // cn/sliew/carp/framework/common/rpc/invocation/LambdaInvocation + System.out.println(serializedLambda.getFunctionalInterfaceClass()); + // run + System.out.println(serializedLambda.getFunctionalInterfaceMethodName()); + // () -> void + System.out.println(serializedLambda.getFunctionalInterfaceMethodSignature()); + + // cn/sliew/carp/framework/common/util/reflection/SerializedLambdaUtil + System.out.println(serializedLambda.getCapturingClass()); + int capturedArgCount = serializedLambda.getCapturedArgCount(); + for (int i = 0; i < capturedArgCount; i++) { + // hello, lambda + System.out.println(serializedLambda.getCapturedArg(i)); + } + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/Autoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/Autoboxer.java new file mode 100644 index 00000000..6c956f58 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/Autoboxer.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.util.Arrays; +import java.util.List; + +public enum Autoboxer { + ; + + private static final List autoboxers = Arrays.asList( + new BooleanTypeAutoboxer(), + new InstantTypeAutoboxer(), + new IntegerTypeAutoboxer(), + new LongTypeAutoboxer(), + new DoubleTypeAutoboxer(), + new FloatTypeAutoboxer(), + new StringTypeAutoboxer(), + new UUIDTypeAutoboxer(), + new EnumAutoboxer(), + new DurationTypeAutoboxer() + ); + + @SuppressWarnings("unchecked") + public static T autobox(Object value, Class type) { + if (value == null) return null; + if (type.isAssignableFrom(value.getClass())) { + return ReflectionUtils.cast(value); + } + + return ReflectionUtils.cast(autoboxers.stream() + .filter(autoboxer -> autoboxer.supports(type)) + .findFirst() + .map(autoboxer -> autoboxer.autobox(value, type)) + .orElseThrow(() -> new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), type.getName())))); + + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/BooleanTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/BooleanTypeAutoboxer.java new file mode 100644 index 00000000..4130ede1 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/BooleanTypeAutoboxer.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.math.BigDecimal; + +public class BooleanTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return Boolean.class.equals(type) || boolean.class.equals(type); + } + + @Override + public Boolean autobox(Object value, Class type) { + if (value instanceof Boolean) { + return (Boolean) value; + } else if (value instanceof BigDecimal) { + return ReflectionUtils.cast(!BigDecimal.ZERO.equals(value)); + } else if (value instanceof Integer) { + return ReflectionUtils.cast(((Integer) value) != 0); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Boolean.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/DoubleTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/DoubleTypeAutoboxer.java new file mode 100644 index 00000000..3b9d4ef9 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/DoubleTypeAutoboxer.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.math.BigDecimal; + +public class DoubleTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return double.class.equals(type) || Double.class.equals(type); + } + + @Override + public Double autobox(Object value, Class type) { + if (value instanceof Double) { + return ReflectionUtils.cast(value); + } else if (value instanceof BigDecimal) { + return ReflectionUtils.cast(((BigDecimal) value).doubleValue()); + } else if (value instanceof Integer) { + return Double.valueOf((Integer) value); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Double.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/DurationTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/DurationTypeAutoboxer.java new file mode 100644 index 00000000..0e315d18 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/DurationTypeAutoboxer.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import java.time.Duration; + +public class DurationTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return Duration.class.equals(type); + } + + @Override + public Duration autobox(Object value, Class type) { + if (value instanceof Duration) { + return (Duration) value; + } else if (value instanceof CharSequence) { + return Duration.parse((CharSequence) value); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Duration.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/EnumAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/EnumAutoboxer.java new file mode 100644 index 00000000..6405f4cc --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/EnumAutoboxer.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +@SuppressWarnings({"rawtypes", "unchecked"}) +public class EnumAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return type.isEnum(); + } + + @Override + public Enum autobox(Object value, Class type) { + return Enum.valueOf(type, value.toString()); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/FloatTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/FloatTypeAutoboxer.java new file mode 100644 index 00000000..b2314034 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/FloatTypeAutoboxer.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.math.BigDecimal; + +public class FloatTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return float.class.equals(type) || Float.class.equals(type); + } + + @Override + public Float autobox(Object value, Class type) { + if (value instanceof Float) { + return ReflectionUtils.cast(value); + } else if (value instanceof BigDecimal) { + return ReflectionUtils.cast(((BigDecimal) value).floatValue()); + } else if (value instanceof String) { + return ReflectionUtils.cast(Long.valueOf((String) value)); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Long.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/InstantTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/InstantTypeAutoboxer.java new file mode 100644 index 00000000..eeef778b --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/InstantTypeAutoboxer.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.sql.Timestamp; +import java.time.Instant; +import java.time.LocalDateTime; + +import static java.time.ZoneId.systemDefault; + +public class InstantTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return Instant.class.equals(type); + } + + @Override + public Instant autobox(Object value, Class type) { + if (value instanceof Timestamp) { + return ReflectionUtils.cast(((Timestamp) value).toInstant()); + } else if (value instanceof Long) { + return ReflectionUtils.cast(new Timestamp((Long) value).toInstant()); + } else if (value instanceof LocalDateTime) { + return ((LocalDateTime) value).atZone(systemDefault()).toInstant(); + } else if (value instanceof CharSequence) { + return Instant.parse((CharSequence) value); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Instant.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/IntegerTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/IntegerTypeAutoboxer.java new file mode 100644 index 00000000..ed233521 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/IntegerTypeAutoboxer.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.math.BigDecimal; + +public class IntegerTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return int.class.equals(type) || Integer.class.equals(type); + } + + @Override + public Integer autobox(Object value, Class type) { + if (value instanceof Integer) { + return ReflectionUtils.cast(value); + } else if (value instanceof BigDecimal) { + return ReflectionUtils.cast(((BigDecimal) value).intValue()); + } else if (value instanceof String) { + return ReflectionUtils.cast(Integer.valueOf((String) value)); + } else if (value instanceof Long) { + return ReflectionUtils.cast(((Long) value).intValue()); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Integer.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/LongTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/LongTypeAutoboxer.java new file mode 100644 index 00000000..07855043 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/LongTypeAutoboxer.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.math.BigDecimal; + +public class LongTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return long.class.equals(type) || Long.class.equals(type); + } + + @Override + public Long autobox(Object value, Class type) { + if (value instanceof Long) { + return ReflectionUtils.cast(value); + } else if (value instanceof BigDecimal) { + return ReflectionUtils.cast(((BigDecimal) value).longValue()); + } else if (value instanceof Integer) { + return ReflectionUtils.cast(Long.valueOf((Integer) value)); + } else if (value instanceof String) { + return ReflectionUtils.cast(Long.valueOf((String) value)); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), Long.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/StringTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/StringTypeAutoboxer.java new file mode 100644 index 00000000..57436b96 --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/StringTypeAutoboxer.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; +import cn.sliew.milky.common.exception.Rethrower; + +import java.sql.Clob; +import java.sql.SQLException; + +public class StringTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return String.class.equals(type); + } + + @Override + public String autobox(Object value, Class type) { + if (value instanceof String) { + return (String) value; + } else if (value instanceof Clob) { + try { + Clob clob = (Clob) value; + return ReflectionUtils.cast(clob.getSubString(1, (int) clob.length())); + } catch (SQLException e) { + Rethrower.throwAs(e); + return null; + } + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), String.class.getName())); + } +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/TypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/TypeAutoboxer.java new file mode 100644 index 00000000..9c8fd6fd --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/TypeAutoboxer.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +public interface TypeAutoboxer { + + boolean supports(Class type); + + T autobox(Object value, Class type); +} diff --git a/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/UUIDTypeAutoboxer.java b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/UUIDTypeAutoboxer.java new file mode 100644 index 00000000..38f91aad --- /dev/null +++ b/carp-framework/carp-framework-common/src/main/java/cn/sliew/carp/framework/common/util/reflection/autobox/UUIDTypeAutoboxer.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.common.util.reflection.autobox; + +import cn.sliew.carp.framework.common.util.reflection.ReflectionUtils; + +import java.util.UUID; + +public class UUIDTypeAutoboxer implements TypeAutoboxer { + @Override + public boolean supports(Class type) { + return UUID.class.equals(type); + } + + @Override + public UUID autobox(Object value, Class type) { + if (value instanceof UUID) { + return (UUID) value; + } else if (value instanceof String) { + return ReflectionUtils.cast(UUID.fromString((String) value)); + } + throw new UnsupportedOperationException(String.format("Cannot autobox %s of type %s to %s", value, value.getClass().getName(), UUID.class.getName())); + } +} diff --git a/carp-framework/carp-framework-dag/pom.xml b/carp-framework/carp-framework-dag/pom.xml index 62eb9677..4ce76803 100644 --- a/carp-framework/carp-framework-dag/pom.xml +++ b/carp-framework/carp-framework-dag/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-dag diff --git a/carp-framework/carp-framework-exception/pom.xml b/carp-framework/carp-framework-exception/pom.xml index 090333ab..65e5448e 100644 --- a/carp-framework/carp-framework-exception/pom.xml +++ b/carp-framework/carp-framework-exception/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-exception diff --git a/carp-framework/carp-framework-license/pom.xml b/carp-framework/carp-framework-license/pom.xml new file mode 100644 index 00000000..d4c6c7cd --- /dev/null +++ b/carp-framework/carp-framework-license/pom.xml @@ -0,0 +1,38 @@ + + + + + 4.0.0 + + cn.sliew + carp-framework + 0.0.13-SNAPSHOT + ../pom.xml + + carp-framework-license + + + + ${project.parent.groupId} + carp-framework-spring + + + + \ No newline at end of file diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/CarpLicense.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/CarpLicense.java new file mode 100644 index 00000000..af620512 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/CarpLicense.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license; + +import cn.sliew.carp.framework.common.dict.license.LicenseType; +import lombok.Data; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.Objects; + +@Data +public class CarpLicense { + + private LicenseType type; + private LocalDateTime expireTime; + + public boolean isValid() { + if (Objects.nonNull(type) && Objects.nonNull(expireTime)) { + return Duration.between(expireTime, LocalDateTime.now()).toMillis() < 0L; + } + return false; + } + + public boolean isPro() { + return isValid() && (type == LicenseType.PRO || type == LicenseType.ENTERPRISE); + } + + public boolean isEnterprise() { + return isValid() && type == LicenseType.ENTERPRISE; + } + +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/CarpLicenseAutoConfiguration.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/CarpLicenseAutoConfiguration.java new file mode 100644 index 00000000..e90da058 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/CarpLicenseAutoConfiguration.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license; + +import cn.hutool.core.date.LocalDateTimeUtil; +import cn.sliew.carp.framework.common.dict.license.LicenseType; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.time.temporal.ChronoUnit; + +@Configuration +public class CarpLicenseAutoConfiguration { + + @Bean + public CarpLicense carpLicense() { + CarpLicense license = new CarpLicense(); + license.setType(LicenseType.TRIAL); + license.setExpireTime(LocalDateTimeUtil.offset(LocalDateTimeUtil.now(), 1, ChronoUnit.DAYS)); + return license; + } +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/EnterpriseLicenseEnabled.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/EnterpriseLicenseEnabled.java new file mode 100644 index 00000000..50a75aa1 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/EnterpriseLicenseEnabled.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.annotation; + +import cn.sliew.carp.framework.license.condition.EnterpriseLicenseCondition; +import org.springframework.context.annotation.Conditional; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Conditional(EnterpriseLicenseCondition.class) +public @interface EnterpriseLicenseEnabled { + +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/ProLicenseEnabled.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/ProLicenseEnabled.java new file mode 100644 index 00000000..da084041 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/ProLicenseEnabled.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.annotation; + +import cn.sliew.carp.framework.license.condition.ProLicenseCondition; +import org.springframework.context.annotation.Conditional; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Conditional(ProLicenseCondition.class) +public @interface ProLicenseEnabled { + +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/ValidLicenseEnabled.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/ValidLicenseEnabled.java new file mode 100644 index 00000000..ff3328e4 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/annotation/ValidLicenseEnabled.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.annotation; + +import cn.sliew.carp.framework.license.condition.ValidLicenseCondition; +import org.springframework.context.annotation.Conditional; + +import java.lang.annotation.*; + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +@Conditional(ValidLicenseCondition.class) +public @interface ValidLicenseEnabled { + +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/aop/LicenseAspect.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/aop/LicenseAspect.java new file mode 100644 index 00000000..8fa3e7e4 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/aop/LicenseAspect.java @@ -0,0 +1,82 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.aop; + +import cn.sliew.carp.framework.license.CarpLicense; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; +import java.util.Objects; + +@Slf4j +@Component +public class LicenseAspect { + + @Autowired(required = false) + private CarpLicense license; + + @Pointcut("@annotation(cn.sliew.carp.framework.license.annotation.ValidLicenseEnabled)") + public void validLicensePointcut() { + } + + @Pointcut("@annotation(cn.sliew.carp.framework.license.annotation.ProLicenseEnabled)") + public void proLicensePointcut() { + } + + @Pointcut("@annotation(cn.sliew.carp.framework.license.annotation.EnterpriseLicenseEnabled)") + public void enterpriseLicensePointcut() { + } + + @Before("validLicensePointcut()") + public void beforeValidLicenseCheck(JoinPoint joinPoint) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + if (Objects.nonNull(license) && license.isValid()) { + return; + } + throw new RuntimeException("license invalid or expired"); + } + + @Before("proLicensePointcut()") + public void beforeProLicenseCheck(JoinPoint joinPoint) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + if (Objects.nonNull(license) && license.isPro()) { + return; + } + throw new RuntimeException("license invalid or expired"); + } + + @Before("enterpriseLicensePointcut()") + public void beforeEnterpriseLicenseCheck(JoinPoint joinPoint) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + if (Objects.nonNull(license) && license.isEnterprise()) { + return; + } + throw new RuntimeException("license invalid or expired"); + } + +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/AbstractLicenseCondition.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/AbstractLicenseCondition.java new file mode 100644 index 00000000..c156b8a5 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/AbstractLicenseCondition.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.condition; + +import cn.sliew.carp.framework.license.CarpLicense; +import org.springframework.boot.autoconfigure.condition.ConditionOutcome; +import org.springframework.boot.autoconfigure.condition.SpringBootCondition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.context.annotation.ConfigurationCondition; +import org.springframework.core.type.AnnotatedTypeMetadata; + +public abstract class AbstractLicenseCondition extends SpringBootCondition implements ConfigurationCondition { + + @Override + public ConfigurationPhase getConfigurationPhase() { + return ConfigurationPhase.REGISTER_BEAN; + } + + @Override + public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { + CarpLicense license = context.getBeanFactory().getBean(CarpLicense.class); + if (licenseMatches(license)) { + return ConditionOutcome.match(); + } + return ConditionOutcome.noMatch("license invalid or expired"); + } + + abstract boolean licenseMatches(CarpLicense license); + +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/EnterpriseLicenseCondition.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/EnterpriseLicenseCondition.java new file mode 100644 index 00000000..d619a540 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/EnterpriseLicenseCondition.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.condition; + +import cn.sliew.carp.framework.license.CarpLicense; + +import java.util.Objects; + +public class EnterpriseLicenseCondition extends AbstractLicenseCondition { + + @Override + boolean licenseMatches(CarpLicense license) { + return Objects.nonNull(license) && license.isEnterprise(); + } +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/ProLicenseCondition.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/ProLicenseCondition.java new file mode 100644 index 00000000..b5df9076 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/ProLicenseCondition.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.condition; + +import cn.sliew.carp.framework.license.CarpLicense; + +import java.util.Objects; + +public class ProLicenseCondition extends AbstractLicenseCondition { + + @Override + boolean licenseMatches(CarpLicense license) { + return Objects.nonNull(license) && license.isPro(); + } +} diff --git a/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/ValidLicenseCondition.java b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/ValidLicenseCondition.java new file mode 100644 index 00000000..a23c4997 --- /dev/null +++ b/carp-framework/carp-framework-license/src/main/java/cn/sliew/carp/framework/license/condition/ValidLicenseCondition.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.license.condition; + +import cn.sliew.carp.framework.license.CarpLicense; + +import java.util.Objects; + +public class ValidLicenseCondition extends AbstractLicenseCondition { + + @Override + boolean licenseMatches(CarpLicense license) { + return Objects.nonNull(license) && license.isValid(); + } +} diff --git a/carp-framework/carp-framework-metrics/pom.xml b/carp-framework/carp-framework-metrics/pom.xml index bfa6771e..7553423b 100644 --- a/carp-framework/carp-framework-metrics/pom.xml +++ b/carp-framework/carp-framework-metrics/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-metrics diff --git a/carp-framework/carp-framework-mongo/pom.xml b/carp-framework/carp-framework-mongo/pom.xml index 1fa3df3c..682fec2b 100644 --- a/carp-framework/carp-framework-mongo/pom.xml +++ b/carp-framework/carp-framework-mongo/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-mongo diff --git a/carp-framework/carp-framework-mybatis/pom.xml b/carp-framework/carp-framework-mybatis/pom.xml index 7366f05b..c5475ee8 100644 --- a/carp-framework/carp-framework-mybatis/pom.xml +++ b/carp-framework/carp-framework-mybatis/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-mybatis diff --git a/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/DataSourceConstants.java b/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/DataSourceConstants.java index 75d9dafa..98243cf6 100644 --- a/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/DataSourceConstants.java +++ b/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/DataSourceConstants.java @@ -23,6 +23,7 @@ public enum DataSourceConstants { public static final String MAPPER_FRAMEWORK_DAG_PACKAGE = "cn.sliew.carp.framework.dag.repository.mapper"; public static final String MAPPER_MODULE_DATASOURCE_PACKAGE = "cn.sliew.carp.module.datasource.repository.mapper"; + public static final String MAPPER_MODULE_HTTP_SYNC_PACKAGE = "cn.sliew.carp.module.http.sync.framework.repository.mapper"; public static final String MAPPER_MODULE_KUBERNETES_PACKAGE = "cn.sliew.carp.module.kubernetes.repository.mapper"; public static final String MAPPER_MODULE_PLUGIN_PACKAGE = "cn.sliew.carp.module.plugin.repository.mapper"; public static final String MAPPER_MODULE_SCHEDULER_PACKAGE = "cn.sliew.carp.module.scheduler.repository.mapper"; diff --git a/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/config/CarpDataSourceConfig.java b/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/config/CarpDataSourceConfig.java index e76f2eec..4da06d19 100644 --- a/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/config/CarpDataSourceConfig.java +++ b/carp-framework/carp-framework-mybatis/src/main/java/cn/sliew/carp/framework/mybatis/config/CarpDataSourceConfig.java @@ -45,6 +45,7 @@ basePackages = { DataSourceConstants.MAPPER_FRAMEWORK_DAG_PACKAGE, DataSourceConstants.MAPPER_MODULE_DATASOURCE_PACKAGE, + DataSourceConstants.MAPPER_MODULE_HTTP_SYNC_PACKAGE, DataSourceConstants.MAPPER_MODULE_KUBERNETES_PACKAGE, DataSourceConstants.MAPPER_MODULE_PLUGIN_PACKAGE, DataSourceConstants.MAPPER_MODULE_SCHEDULER_PACKAGE, diff --git a/carp-framework/carp-framework-pekko/pom.xml b/carp-framework/carp-framework-pekko/pom.xml index 2672da5e..c21e70a0 100644 --- a/carp-framework/carp-framework-pekko/pom.xml +++ b/carp-framework/carp-framework-pekko/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-pekko diff --git a/carp-framework/carp-framework-redis/pom.xml b/carp-framework/carp-framework-redis/pom.xml index 1df34e7d..135f2dd6 100644 --- a/carp-framework/carp-framework-redis/pom.xml +++ b/carp-framework/carp-framework-redis/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-redis diff --git a/carp-framework/carp-framework-redis/src/main/java/cn/sliew/carp/framework/redis/config/RedissionConfig.java b/carp-framework/carp-framework-redis/src/main/java/cn/sliew/carp/framework/redis/config/RedissionConfig.java index 7d0ef274..2cbbc30a 100644 --- a/carp-framework/carp-framework-redis/src/main/java/cn/sliew/carp/framework/redis/config/RedissionConfig.java +++ b/carp-framework/carp-framework-redis/src/main/java/cn/sliew/carp/framework/redis/config/RedissionConfig.java @@ -26,6 +26,8 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.context.annotation.Configuration; +import java.time.Duration; + @Configuration @AutoConfigureBefore(RedissonAutoConfiguration.class) public class RedissionConfig implements RedissonAutoConfigurationCustomizer { @@ -34,5 +36,6 @@ public class RedissionConfig implements RedissonAutoConfigurationCustomizer { public void customize(Config config) { SingleServerConfig singleServerConfig = config.useSingleServer(); singleServerConfig.setAddress(NetUtil.replaceLocalhost(singleServerConfig.getAddress())); + config.setLockWatchdogTimeout(Duration.ofSeconds(10L).toMillis()); } } diff --git a/carp-framework/carp-framework-spring/pom.xml b/carp-framework/carp-framework-spring/pom.xml index 3d2ec1b5..c0cb5802 100644 --- a/carp-framework/carp-framework-spring/pom.xml +++ b/carp-framework/carp-framework-spring/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-spring @@ -38,6 +38,15 @@ org.springframework.boot spring-boot-starter + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-actuator + \ No newline at end of file diff --git a/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/concurrent/MetricsTaskDecorator.java b/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/concurrent/MetricsTaskDecorator.java new file mode 100644 index 00000000..446cf631 --- /dev/null +++ b/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/concurrent/MetricsTaskDecorator.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.spring.concurrent; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Timer; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.time.StopWatch; +import org.springframework.core.task.TaskDecorator; + +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class MetricsTaskDecorator implements TaskDecorator { + + private List tags; + private MeterRegistry meterRegistry; + + public MetricsTaskDecorator(List tags, MeterRegistry meterRegistry) { + this.tags = tags; + this.meterRegistry = meterRegistry; + } + + @Override + public Runnable decorate(Runnable runnable) { + return new JobMetricsRunnable(runnable); + } + + private class JobMetricsRunnable implements Runnable { + + private final Runnable task; + + private JobMetricsRunnable(Runnable task) { + this.task = task; + } + + @Override + public void run() { + try { + StopWatch stopWatch = StopWatch.createStarted(); + task.run(); + stopWatch.stop(); + recordTaskCostTime(stopWatch.getTime(TimeUnit.MILLISECONDS)); + } catch (Throwable e) { + log.error("failed to run! task: {}", task.toString(), e); + } + } + + private void recordTaskCostTime(long costInMills) { + if (meterRegistry != null) { + try { + Timer.builder("job_thread_pool_tasks") + .tags(tags) + .publishPercentileHistogram(true) + .register(meterRegistry) + .record(costInMills, TimeUnit.MILLISECONDS); + } catch (Exception e) { + log.warn("Fail to record thread pool task timer metrics", e); + } + } + } + + @Override + public int hashCode() { + return task.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return task.equals(obj); + } + + @Override + public String toString() { + return "[task-executor-wrapper] task: " + task.toString(); + } + } +} diff --git a/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/concurrent/MetricsThreadPoolExecutor.java b/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/concurrent/MetricsThreadPoolExecutor.java new file mode 100644 index 00000000..8366fe35 --- /dev/null +++ b/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/concurrent/MetricsThreadPoolExecutor.java @@ -0,0 +1,129 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.spring.concurrent; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Timer; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.TimeUnit; + +@Slf4j +public class MetricsThreadPoolExecutor extends ThreadPoolTaskExecutor { + + /** + * 任务开始时间 + */ + private final ThreadLocal startTimeThreadLocal = new ThreadLocal<>(); + + private MeterRegistry meterRegistry; + + private List tags; + + @Override + public void initialize() { + super.initialize(); + enableMetrics(getThreadNamePrefix()); + } + + private void enableMetrics(String poolName) { + this.tags = Collections.singletonList(Tag.of("pool_name", poolName)); + startWatch(); + } + + private void startWatch() { + meterRegistry.gauge("job_thread_pool_active_thread_size", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getActiveCount()); + meterRegistry.gauge("job_thread_pool_pool_size", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getPoolSize()); + meterRegistry.gauge("job_thread_pool_core_pool_size", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getCorePoolSize()); + meterRegistry.gauge("job_thread_pool_max_pool_size", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getMaxPoolSize()); + meterRegistry.gauge("job_thread_pool_task_total", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getThreadPoolExecutor().getTaskCount()); + meterRegistry.gauge("job_thread_pool_completed_task_total", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getThreadPoolExecutor().getCompletedTaskCount()); + meterRegistry.gauge("job_thread_pool_queue_size", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getQueueSize()); + meterRegistry.gauge("job_thread_pool_queue_capacity", + getTags(), + this, + threadPoolExecutor -> (double) threadPoolExecutor.getQueueCapacity()); + } + + private List getTags() { + return tags; + } + + + /** + * 任务执行之前,记录任务开始时间 + */ + @Override + protected void beforeExecute(Thread t, Runnable r) { + startTimeThreadLocal.set(System.currentTimeMillis()); + } + + /** + * 任务执行之后,计算任务结束时间 + */ + @Override + protected void afterExecute(Runnable r, Throwable t) { + try { + long costTime = System.currentTimeMillis() - startTimeThreadLocal.get(); + recordTaskCostTime(costTime); + } finally { + startTimeThreadLocal.remove(); + } + } + + + private void recordTaskCostTime(long costInMills) { + try { + Timer.builder("job_thread_pool_tasks") + .tags(getTags()) + .publishPercentileHistogram(true) + .register(meterRegistry) + .record(costInMills, TimeUnit.MILLISECONDS); + } catch (Exception e) { + log.warn("Fail to record thread pool task timer metrics", e); + } + } + + +} diff --git a/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/config/AsyncConfig.java b/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/config/AsyncConfig.java new file mode 100644 index 00000000..857de9b2 --- /dev/null +++ b/carp-framework/carp-framework-spring/src/main/java/cn/sliew/carp/framework/spring/config/AsyncConfig.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.spring.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.annotation.AsyncConfigurer; + +@Configuration +public class AsyncConfig implements AsyncConfigurer { + + +} diff --git a/carp-framework/carp-framework-task/pom.xml b/carp-framework/carp-framework-task/pom.xml index f9c39bd6..0d630a0b 100644 --- a/carp-framework/carp-framework-task/pom.xml +++ b/carp-framework/carp-framework-task/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-task @@ -37,5 +37,10 @@ ${project.parent.groupId} carp-framework-exception + + + ${project.parent.groupId} + carp-framework-redis + \ No newline at end of file diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskClient.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskClient.java new file mode 100644 index 00000000..67599f26 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskClient.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server; + +import cn.sliew.carp.framework.task.server.detail.TaskDetail; + +import java.time.Duration; + +public interface TaskClient { + + /** + * fire-forget 任务,优先级任务,定时任务 + */ + String publish(String topic, TaskDetail task, Duration delay); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskClientImpl.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskClientImpl.java new file mode 100644 index 00000000..51ab0405 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskClientImpl.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server; + +import cn.sliew.carp.framework.task.server.broker.TaskBroker; +import cn.sliew.carp.framework.task.server.detail.TaskDetail; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Component; + +import java.time.Duration; + +@Component +@AllArgsConstructor +public class TaskClientImpl implements TaskClient { + + private TaskBroker taskBroker; + + @Override + public String publish(String topic, TaskDetail task, Duration delay) { + return taskBroker.sendTask(topic, task, delay).getId(); + } +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskScheduler.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskScheduler.java new file mode 100644 index 00000000..90208823 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/TaskScheduler.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server; + +public interface TaskScheduler { + + +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/TaskBroker.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/TaskBroker.java new file mode 100644 index 00000000..718ec9e4 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/TaskBroker.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker; + +import cn.sliew.carp.framework.task.server.detail.TaskDetail; +import cn.sliew.carp.framework.task.server.storage.StorageProvider; + +import java.time.Duration; + +public interface TaskBroker { + + TaskMessage sendTask(String topic, TaskDetail taskDetail, Duration delay); + + TaskMessage getTask(String topic, String id); + + TaskMessage deleteTask(String topic, String id); + + StorageProvider getStorageProvider(); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/TaskMessage.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/TaskMessage.java new file mode 100644 index 00000000..829a0ad2 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/TaskMessage.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker; + +public interface TaskMessage { + + String getId(); + + Integer getStatus(); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/DefaultTaskMessage.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/DefaultTaskMessage.java new file mode 100644 index 00000000..d8bb65c9 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/DefaultTaskMessage.java @@ -0,0 +1,23 @@ +package cn.sliew.carp.framework.task.server.broker.impl; + +import cn.sliew.carp.framework.task.server.broker.TaskMessage; +import cn.sliew.carp.framework.task.server.detail.TaskDetail; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class DefaultTaskMessage implements TaskMessage { + + private String id; + private Integer status; + + private String topic; + private TaskDetail taskDetail; + private Long produceTime; + private Long triggerTime; +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/RedissonTaskBroker.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/RedissonTaskBroker.java new file mode 100644 index 00000000..1f691293 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/RedissonTaskBroker.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker.impl; + +import cn.sliew.carp.framework.task.server.broker.TaskBroker; +import cn.sliew.carp.framework.task.server.broker.TaskMessage; +import cn.sliew.carp.framework.task.server.detail.TaskDetail; +import cn.sliew.carp.framework.task.server.storage.StorageProvider; +import cn.sliew.carp.framework.task.server.storage.TaskResultStorage; +import cn.sliew.carp.framework.task.server.worker.impl.RedissonTaskWorker; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import org.redisson.api.RScheduledExecutorService; +import org.redisson.api.RScheduledFuture; +import org.redisson.api.RedissonClient; +import org.redisson.api.WorkerOptions; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.TimeUnit; + +@Component +@RequiredArgsConstructor +public class RedissonTaskBroker implements TaskBroker { + + private RedissonClient client; + private TaskStartedListenerImpl taskStartedListener;; + private TaskFinishedListenerImpl taskFinishedListener; + private TaskSuccessListenerImpl taskSuccessListener; + private TaskFailureListenerImpl taskFailureListener; + + private ConcurrentMap executorServiceMap = new ConcurrentHashMap<>(); + + @Override + public TaskMessage sendTask(String topic, TaskDetail taskDetail, Duration delay) { + RScheduledExecutorService executorService = executorServiceMap.computeIfAbsent(topic, key -> buildExecutorService(key)); + + RScheduledFuture future = executorService.schedule(new RedissonTaskWorker(topic, taskDetail), delay.toMillis(), TimeUnit.MILLISECONDS); + TaskResultStorage taskResultStorage = getStorageProvider().getTaskResultStorage(); + // 写入任务结果 + return getTask(topic, future.getTaskId()); + } + + @Override + public TaskMessage getTask(String topic, String id) { + RScheduledExecutorService executorService = executorServiceMap.computeIfAbsent(topic, key -> buildExecutorService(key)); + // 读取任务结果 + TaskResultStorage taskResultStorage = getStorageProvider().getTaskResultStorage(); + + return null; + } + + @Override + public TaskMessage deleteTask(String topic, String id) { + RScheduledExecutorService executorService = client.getExecutorService(topic); + executorService.cancelTask(id); + TaskMessage taskMessage = getTask(topic, id); + + // 更新为被删除任务信息 + TaskResultStorage taskResultStorage = getStorageProvider().getTaskResultStorage(); + return taskMessage; + } + + @Override + public StorageProvider getStorageProvider() { + return null; + } + + private RScheduledExecutorService buildExecutorService(String topic) { + RScheduledExecutorService executorService = client.getExecutorService(topic); + WorkerOptions workerOptions = WorkerOptions.defaults() + .workers(2) + .taskTimeout(60, TimeUnit.SECONDS) + .addListener(taskStartedListener) + .addListener(taskFinishedListener) + .addListener(taskSuccessListener) + .addListener(taskFailureListener); + executorService.registerWorkers(workerOptions); + return executorService; + } +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskFailureListenerImpl.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskFailureListenerImpl.java new file mode 100644 index 00000000..32a54ef3 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskFailureListenerImpl.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker.impl; + +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.executor.TaskFailureListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class TaskFailureListenerImpl implements TaskFailureListener { + + @Override + public void onFailed(String taskId, Throwable exception) { + log.error("redisson failed, taskId: {}", taskId, exception); + } +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskFinishedListenerImpl.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskFinishedListenerImpl.java new file mode 100644 index 00000000..52052757 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskFinishedListenerImpl.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker.impl; + +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.executor.TaskFinishedListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class TaskFinishedListenerImpl implements TaskFinishedListener { + + @Override + public void onFinished(String taskId) { + log.info("redisson finished, taskId: {}", taskId); + } +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskStartedListenerImpl.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskStartedListenerImpl.java new file mode 100644 index 00000000..dd74889c --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskStartedListenerImpl.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker.impl; + +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.executor.TaskStartedListener; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class TaskStartedListenerImpl implements TaskStartedListener { + + @Override + public void onStarted(String taskId) { + log.info("redisson started, taskId: {}", taskId); + } +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskSuccessListenerImpl.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskSuccessListenerImpl.java new file mode 100644 index 00000000..38b3b3a4 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/broker/impl/TaskSuccessListenerImpl.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.broker.impl; + +import cn.sliew.milky.common.util.JacksonUtil; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.executor.TaskSuccessListener; +import org.springframework.stereotype.Component; + +import java.util.Map; + +@Slf4j +@Component +public class TaskSuccessListenerImpl implements TaskSuccessListener { + + private Map taskResultRepository = Maps.newHashMap(); + + @Override + public void onSucceeded(String taskId, T result) { + taskResultRepository.put(taskId, result); + log.info("redisson success, taskId: {}, result: {}", taskId, JacksonUtil.toJsonString(result)); + } +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskDetail.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskDetail.java new file mode 100644 index 00000000..5cb0b378 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskDetail.java @@ -0,0 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.detail; + +public interface TaskDetail { +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskInfo.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskInfo.java new file mode 100644 index 00000000..de44052c --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskInfo.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.detail; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TaskInfo implements TaskDetail, Serializable { + + private static final long serialVersionUID = 1L; + + private String className; + private String methodName; + private List params; +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskParam.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskParam.java new file mode 100644 index 00000000..935bcd78 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/detail/TaskParam.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.detail; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class TaskParam implements Serializable { + + public static final long serialVersionUID = 1L; + + private String className; + private String actualClassName; + private Object object; +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/handler/TaskHandler.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/handler/TaskHandler.java new file mode 100644 index 00000000..e3f3895c --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/handler/TaskHandler.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.handler; + +import cn.sliew.carp.framework.task.server.detail.TaskDetail; + +public interface TaskHandler { + + void onTask(String topic, TaskDetail task); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/serder/Serder.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/serder/Serder.java new file mode 100644 index 00000000..5964ff0d --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/serder/Serder.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.serder; + +import cn.sliew.carp.framework.task.server.detail.TaskDetail; + +public interface Serder { + + byte[] serialize(TaskDetail taskDetail); + + TaskDetail deserialize(byte[] bytes); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/BrokerStorage.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/BrokerStorage.java new file mode 100644 index 00000000..7090f1cd --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/BrokerStorage.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.storage; + +public interface BrokerStorage { + +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/StorageProvider.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/StorageProvider.java new file mode 100644 index 00000000..eb4bf1f1 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/StorageProvider.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.storage; + +public interface StorageProvider { + + BrokerStorage getBrokerStorage(); + + TaskResultStorage getTaskResultStorage(); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/TaskResultStorage.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/TaskResultStorage.java new file mode 100644 index 00000000..8108b2da --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/storage/TaskResultStorage.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.storage; + +import cn.sliew.carp.framework.task.server.broker.TaskMessage; + +public interface TaskResultStorage { + + TaskMessage getTask(String taskId); + + TaskMessage getTaskResult(String taskId); + + TaskMessage deleteTask(String taskId); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/worker/TaskWorker.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/worker/TaskWorker.java new file mode 100644 index 00000000..536cd975 --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/worker/TaskWorker.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.worker; + +public interface TaskWorker { + + void start(); + + void stop(); +} diff --git a/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/worker/impl/RedissonTaskWorker.java b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/worker/impl/RedissonTaskWorker.java new file mode 100644 index 00000000..d7105d6b --- /dev/null +++ b/carp-framework/carp-framework-task/src/main/java/cn/sliew/carp/framework/task/server/worker/impl/RedissonTaskWorker.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.task.server.worker.impl; + +import cn.sliew.carp.framework.task.TaskExecutor; +import cn.sliew.carp.framework.task.server.detail.TaskDetail; +import cn.sliew.carp.framework.task.server.handler.TaskHandler; +import cn.sliew.carp.framework.task.server.worker.TaskWorker; +import cn.sliew.milky.common.concurrent.RunnableWrapper; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RedissonClient; +import org.redisson.api.annotation.RInject; + +@Slf4j +public class RedissonTaskWorker implements TaskWorker, RunnableWrapper { + + private RedissonClient client; + private TaskHandler taskHandler; + private TaskExecutor executor; + + private String topic; + private TaskDetail taskDetail; + + @RInject + private String taskId; + + public RedissonTaskWorker(String topic, TaskDetail taskDetail) { + this.topic = topic; + this.taskDetail = taskDetail; + } + + @Override + public void start() { + + } + + @Override + public void stop() { + + } + + @Override + public void onBefore() throws Exception { + // 保存任务状态 + } + + @Override + public void doRun() throws Exception { + // 执行 executor + log.info("[}", taskDetail); + } + + @Override + public void onAfter() throws Exception { + // 记录任务成功 + } + + @Override + public void onFailure(Exception e) { + // 记录任务失败 + } + + @Override + public void onFinal() { + // 最后根据任务执行结果 + // 成功,标记任务结束 + // 失败,标记任务失败,如果支持重试,则进行重试 + } + +} diff --git a/carp-framework/carp-framework-web/pom.xml b/carp-framework/carp-framework-web/pom.xml index 7a9738f3..f04301cd 100644 --- a/carp-framework/carp-framework-web/pom.xml +++ b/carp-framework/carp-framework-web/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-framework - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework-web diff --git a/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/ExceptionFactory.java b/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/ExceptionFactory.java new file mode 100644 index 00000000..de89e48b --- /dev/null +++ b/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/ExceptionFactory.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.framework.web.exception; + +import org.springframework.http.HttpStatus; +import org.springframework.http.ProblemDetail; +import org.springframework.web.ErrorResponseException; + +import java.net.URI; + +public enum ExceptionFactory { + ; + + public static ErrorResponseException convertException(Exception e) { + ProblemDetail pd = ProblemDetail.forStatus(HttpStatus.INTERNAL_SERVER_ERROR); + pd.setType(URI.create("https://github.com/flowerfine/carp/issues")); + pd.setTitle(e.getMessage()); + return new ErrorResponseException(HttpStatus.INTERNAL_SERVER_ERROR, pd, e); + } + +} diff --git a/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/GlobalExceptionHandler.java b/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/GlobalExceptionHandler.java index 24bea699..76f99c97 100644 --- a/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/GlobalExceptionHandler.java +++ b/carp-framework/carp-framework-web/src/main/java/cn/sliew/carp/framework/web/exception/GlobalExceptionHandler.java @@ -28,16 +28,20 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.BindException; -import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; +import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; import java.util.HashMap; import java.util.Map; +/** + * @see DefaultHandlerExceptionResolver + */ @Slf4j -@ControllerAdvice -public class GlobalExceptionHandler { +@RestControllerAdvice +public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { /** * All exception handling converters @@ -53,7 +57,6 @@ public class GlobalExceptionHandler { REGISTRY.put(BindException.class, new BindExceptionConvertor()); } - @ResponseBody @ExceptionHandler(Throwable.class) public ResponseEntity exception(Throwable exception, HttpServletRequest request, @@ -62,7 +65,7 @@ public ResponseEntity exception(Throwable exception, return new ResponseEntity<>(errorInfo, HttpStatus.OK); } - public ResponseVO convert(Throwable exception,HttpServletRequest request, HttpServletResponse response) { + public ResponseVO convert(Throwable exception, HttpServletRequest request, HttpServletResponse response) { ExceptionConvertor exceptionConvertor = REGISTRY.get(exception.getClass()); if (exceptionConvertor == null) { if (exception instanceof SliewException) { diff --git a/carp-framework/pom.xml b/carp-framework/pom.xml index 21a062b1..d8d0a4c2 100644 --- a/carp-framework/pom.xml +++ b/carp-framework/pom.xml @@ -23,13 +23,14 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-framework pom + carp-framework-biz carp-framework-common carp-framework-dag carp-framework-exception @@ -41,6 +42,7 @@ carp-framework-spring carp-framework-task carp-framework-web + carp-framework-license \ No newline at end of file diff --git a/carp-modules/carp-module-alert/pom.xml b/carp-modules/carp-module-alert/pom.xml index 156511b8..8dc1ba9c 100644 --- a/carp-modules/carp-module-alert/pom.xml +++ b/carp-modules/carp-module-alert/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-alert diff --git a/carp-modules/carp-module-application/carp-module-application-controller/pom.xml b/carp-modules/carp-module-application/carp-module-application-controller/pom.xml index 2b4cf4d5..c9d3e021 100644 --- a/carp-modules/carp-module-application/carp-module-application-controller/pom.xml +++ b/carp-modules/carp-module-application/carp-module-application-controller/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-application - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-application-controller diff --git a/carp-modules/carp-module-application/carp-module-application-oam/pom.xml b/carp-modules/carp-module-application/carp-module-application-oam/pom.xml index b75a2c1c..11fcbdf2 100644 --- a/carp-modules/carp-module-application/carp-module-application-oam/pom.xml +++ b/carp-modules/carp-module-application/carp-module-application-oam/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-application - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-application-oam diff --git a/carp-modules/carp-module-application/carp-module-application-vela/pom.xml b/carp-modules/carp-module-application/carp-module-application-vela/pom.xml index f525107d..4069b77a 100644 --- a/carp-modules/carp-module-application/carp-module-application-vela/pom.xml +++ b/carp-modules/carp-module-application/carp-module-application-vela/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-application - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-application-vela diff --git a/carp-modules/carp-module-application/pom.xml b/carp-modules/carp-module-application/pom.xml index 28061c9d..32539073 100644 --- a/carp-modules/carp-module-application/pom.xml +++ b/carp-modules/carp-module-application/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-application diff --git a/carp-modules/carp-module-datasource/pom.xml b/carp-modules/carp-module-datasource/pom.xml index 04235760..c287ab69 100644 --- a/carp-modules/carp-module-datasource/pom.xml +++ b/carp-modules/carp-module-datasource/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-datasource diff --git a/carp-modules/carp-module-datasource/src/main/java/cn/sliew/carp/module/datasource/modal/AbstractDataSourceProperties.java b/carp-modules/carp-module-datasource/src/main/java/cn/sliew/carp/module/datasource/modal/AbstractDataSourceProperties.java index 7864f49e..c5b35523 100644 --- a/carp-modules/carp-module-datasource/src/main/java/cn/sliew/carp/module/datasource/modal/AbstractDataSourceProperties.java +++ b/carp-modules/carp-module-datasource/src/main/java/cn/sliew/carp/module/datasource/modal/AbstractDataSourceProperties.java @@ -42,6 +42,7 @@ @JsonIgnoreProperties(ignoreUnknown = true) public abstract class AbstractDataSourceProperties implements Polymorphic { + @Override public abstract String getType(); public static final class DataSourceResolver extends PolymorphicResolver { diff --git a/carp-modules/carp-module-excel/pom.xml b/carp-modules/carp-module-excel/pom.xml new file mode 100644 index 00000000..d0be12e4 --- /dev/null +++ b/carp-modules/carp-module-excel/pom.xml @@ -0,0 +1,52 @@ + + + + + 4.0.0 + + cn.sliew + carp-modules + 0.0.13-SNAPSHOT + ../pom.xml + + carp-module-excel + + + + ${project.parent.groupId} + carp-framework-mybatis + + + ${project.parent.groupId} + carp-framework-web + + + + com.alibaba + easyexcel + + + + org.pf4j + pf4j + + + + \ No newline at end of file diff --git a/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/config/ExcelOpenAPIConfig.java b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/config/ExcelOpenAPIConfig.java new file mode 100644 index 00000000..c0dc958a --- /dev/null +++ b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/config/ExcelOpenAPIConfig.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.excel.config; + +import org.springdoc.core.models.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class ExcelOpenAPIConfig { + + @Bean + public GroupedOpenApi carpDataSourceModuleOpenApi() { + return GroupedOpenApi.builder().group("Excel模块") + .pathsToMatch("/api/carp/excel/**") + .packagesToScan("cn.sliew.carp.module.excel").build(); + } +} \ No newline at end of file diff --git a/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/annotaion/ImportSpec.java b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/annotaion/ImportSpec.java new file mode 100644 index 00000000..ebd8bfac --- /dev/null +++ b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/annotaion/ImportSpec.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.excel.core.annotaion; + +import java.lang.annotation.*; + +@Documented +@Inherited +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ImportSpec { + + String code(); + + String name(); + + String desc() default ""; + + String fileType() default "xlsx"; +} diff --git a/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/Processor.java b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/Processor.java new file mode 100644 index 00000000..2fd3d4e9 --- /dev/null +++ b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/Processor.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.excel.core.processor; + +public interface Processor { + +} diff --git a/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/exporter/ExportProcessor.java b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/exporter/ExportProcessor.java new file mode 100644 index 00000000..5f231744 --- /dev/null +++ b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/exporter/ExportProcessor.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.excel.core.processor.exporter; + +import cn.sliew.carp.module.excel.core.processor.Processor; + +public interface ExportProcessor extends Processor { +} diff --git a/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/importer/ImportProcessor.java b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/importer/ImportProcessor.java new file mode 100644 index 00000000..0fa3492b --- /dev/null +++ b/carp-modules/carp-module-excel/src/main/java/cn/sliew/carp/module/excel/core/processor/importer/ImportProcessor.java @@ -0,0 +1,25 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.excel.core.processor.importer; + +import cn.sliew.carp.module.excel.core.processor.Processor; + +public interface ImportProcessor extends Processor { + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/pom.xml b/carp-modules/carp-module-http-sync/carp-module-http-framework/pom.xml new file mode 100644 index 00000000..c46ef87b --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/pom.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + cn.sliew + carp-module-http-sync + 0.0.13-SNAPSHOT + ../pom.xml + + carp-module-http-framework + + + + ${project.parent.groupId} + carp-framework-mybatis + + + ${project.parent.groupId} + carp-framework-pekko + + + \ No newline at end of file diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractJob.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractJob.java new file mode 100644 index 00000000..0296bb78 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractJob.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.ProcessResult; +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import cn.sliew.milky.common.exception.Rethrower; +import cn.sliew.milky.common.util.JacksonUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.pekko.Done; +import org.apache.pekko.NotUsed; +import org.apache.pekko.actor.typed.ActorSystem; +import org.apache.pekko.actor.typed.SpawnProtocol; +import org.apache.pekko.japi.Pair; +import org.apache.pekko.stream.*; +import org.apache.pekko.stream.javadsl.*; + +import java.util.concurrent.CompletionStage; +import java.util.concurrent.TimeUnit; + +@Slf4j +public abstract class AbstractJob implements Job { + + protected ActorSystem actorSystem; + protected SyncOffsetManager syncOffsetManager; + protected SplitManager splitManager; + + public AbstractJob(ActorSystem actorSystem, SyncOffsetManager syncOffsetManager, SplitManager splitManager) { + this.actorSystem = actorSystem; + this.syncOffsetManager = syncOffsetManager; + this.splitManager = splitManager; + } + + @Override + public void process(String param) { + doExecute(param); + } + + protected void doExecute(Object param) { + SimpleJobContext context = buildJobContext(); + JobProcessor processor = buildJobProcessor(context); + RootTask rootTask = buildRootTask(param); + + Source source = Source.single(rootTask) + .mapConcat(root -> processor.map(root)) + .viaMat(KillSwitches.single(), Keep.right()); + + Flow process = Flow.create() + .map(subTask -> processor.process(subTask)).mapAsync(1, future -> future); + + Flow subTasks = + Flow.fromGraph( + GraphDSL.create( + b -> { + int concurrency = context.getSubTaskParallelism(); + UniformFanOutShape partition = + b.add(Partition.create(concurrency, subTask -> Math.toIntExact(subTask.getIdentifier()) % concurrency)); + UniformFanInShape merge = + b.add(MergeSequence.create(concurrency, result -> result.getSubTask().getIdentifier())); + + for (int i = 0; i < concurrency; i++) { + b.from(partition.out(i)) + .via(b.add(process.async())) + .viaFanIn(merge); + } + + return FlowShape.of(partition.in(), merge.out()); + })); + + Pair> pair = source.via(subTasks) + .log(getJobName()) + .toMat(Sink.foreach(result -> processor.reduce(result)), Keep.both()) + .run(actorSystem); + UniqueKillSwitch killSwitch = pair.first(); + try { + pair.second().toCompletableFuture().get(1, TimeUnit.HOURS); + } catch (Exception e) { + log.error("job 执行异常, job: {}, param: {}", getJobName(), JacksonUtil.toJsonString(param)); + killSwitch.abort(e); + Rethrower.throwAs(e); + } + } + + public abstract String getJobName(); + + protected SimpleJobContext buildJobContext() { + SimpleJobContext jobContext = new SimpleJobContext(); + jobContext.setActorSystem(actorSystem); + jobContext.setSyncOffsetManager(syncOffsetManager); + jobContext.setSplitManager(splitManager); + return jobContext; + } + + protected JobProcessor buildJobProcessor(SimpleJobContext context) { + return new DefaultJobProcessor(context); + } + + protected abstract RootTask buildRootTask(Object param); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractRootTask.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractRootTask.java new file mode 100644 index 00000000..c3f27c7d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractRootTask.java @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import cn.sliew.carp.module.http.sync.framework.repository.entity.JobSyncOffset; +import org.apache.pekko.japi.Pair; + +import java.time.Duration; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; + +public abstract class AbstractRootTask implements RootTask { + + private Long rootTaskId; + + public AbstractRootTask(Long rootTaskId) { + this.rootTaskId = rootTaskId; + } + + @Override + public Long getIdentifier() { + return rootTaskId; + } + + @Override + public List split(SimpleJobContext context) { + SyncOffsetManager syncOffsetManager = context.getSyncOffsetManager(); + JobSyncOffset syncOffset = syncOffsetManager.getSyncOffset(context); + + SplitManager splitManager = context.getSplitManager(); + Optional optional = splitManager.getGradients().stream() + .filter(gradient -> splitManager.supportSplit(syncOffset.getSyncOffset(), context.getFinalSyncOffset(), gradient)) + .findFirst(); + Duration gradient = null; + if (optional.isEmpty()) { + boolean backupSupport = splitManager.supportSplit(syncOffset.getSyncOffset(), context.getFinalSyncOffset(), splitManager.getBackoffGradient()); + if (backupSupport) { + gradient = splitManager.getBackoffGradient(); + } + } else { + gradient = optional.get(); + } + if (gradient == null) { + return Collections.emptyList(); + } + List> splits = context.getSplitManager().split(syncOffset.getSyncOffset(), context.getFinalSyncOffset(), gradient, context.getSubTaskBatchSize()); + + List subs = new ArrayList<>(); + for (int i = 0; i < splits.size(); i++) { + Pair pair = splits.get(i); + subs.add(build(Long.valueOf(i), pair.first(), pair.second())); + } + return subs; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractSubTask.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractSubTask.java new file mode 100644 index 00000000..2d828df4 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/AbstractSubTask.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.ProcessResult; +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import org.apache.pekko.Done; +import org.apache.pekko.actor.typed.ActorSystem; +import org.apache.pekko.stream.ActorAttributes; +import org.apache.pekko.stream.javadsl.Sink; +import org.apache.pekko.stream.javadsl.Source; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; + +public abstract class AbstractSubTask implements SubTask { + + private final Long subTaskId; + private final Root rootTask; + + private final String startSyncOffset; + private final String endSyncOffset; + + public AbstractSubTask(Long subTaskId, Root rootTask, String startSyncOffset, String endSyncOffset) { + this.subTaskId = subTaskId; + this.rootTask = rootTask; + this.startSyncOffset = startSyncOffset; + this.endSyncOffset = endSyncOffset; + } + + @Override + public Long getIdentifier() { + return subTaskId; + } + + @Override + public Root getRootTask() { + return rootTask; + } + + @Override + public String getStartSyncOffset() { + return startSyncOffset; + } + + @Override + public String getEndSyncOffset() { + return endSyncOffset; + } + + @Override + public CompletableFuture execute(SimpleJobContext context) { + ActorSystem actorSystem = context.getActorSystem(); + Sink, CompletionStage> sink = Sink.foreachParallel(10, data -> persistData(context, data.getRequest(), data.getResponse()), actorSystem.executionContext()); + Source, ?> source = fetch(context); + CompletionStage completionStage = source + // 指定 dispatcher +// .withAttributes(ActorAttributes.dispatcher("akka.actor.job-sink-dispatcher")) + .runWith(sink, actorSystem); + return completionStage.thenApply(done -> ProcessResult.success(this)).toCompletableFuture(); + } + + protected abstract Source, ?> fetch(SimpleJobContext context); + + protected abstract Request buildFirstRequest(SimpleJobContext context); + + protected abstract Response requestRemote(SimpleJobContext context, Request request); + + protected abstract void persistData(SimpleJobContext context, Request request, Response response); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultJobProcessor.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultJobProcessor.java new file mode 100644 index 00000000..f2788e52 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultJobProcessor.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.ProcessResult; +import cn.sliew.milky.common.exception.Rethrower; +import cn.sliew.milky.common.util.JacksonUtil; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Slf4j +public class DefaultJobProcessor + implements JobProcessor { + + private final Context context; + + public DefaultJobProcessor(Context context) { + this.context = context; + } + + @Override + public Context getContext() { + return context; + } + + @Override + public List map(Root rootTask) { + return rootTask.split(getContext()); + } + + @Override + public CompletableFuture process(Sub subTask) { + return subTask.execute(context); + } + + @Override + public ProcessResult reduce(ProcessResult result) { + if (result.isSuccess() == false) { + log.error("group: {}, job: {}, subJob: {}, 子任务处理失败: {}!", + context.getGroup(), context.getJob(), context.getSubJob().orElse(null), + result.getMessage(), result.getThrowable()); + if (result.getThrowable() != null) { + Rethrower.throwAs(result.getThrowable()); + } + throw new RuntimeException(result.getMessage()); + } + SubTask subTask = result.getSubTask(); + log.debug("group: {}, job: {}, subJob: {}, {}-{}, 子任务处理成功! 子任务详情: {}", + context.getGroup(), context.getJob(), context.getSubJob().orElse(null), + subTask.getRootTask().getIdentifier(), subTask.getIdentifier(), + JacksonUtil.toJsonString(subTask)); + context.getSyncOffsetManager().updateSyncOffset(context, subTask.getEndSyncOffset()); + return ProcessResult.success(result.getSubTask()); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultSplitManager.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultSplitManager.java new file mode 100644 index 00000000..b50fcf21 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultSplitManager.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.util.GradientUtil; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.List; + +@Component +public class DefaultSplitManager implements SplitManager { + + @Override + public List getGradients() { + return GradientUtil.getDefaultGradients(); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultSyncOffsetManager.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultSyncOffsetManager.java new file mode 100644 index 00000000..fff12eb8 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/DefaultSyncOffsetManager.java @@ -0,0 +1,98 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import cn.sliew.carp.module.http.sync.framework.repository.entity.JobSyncOffset; +import cn.sliew.carp.module.http.sync.framework.repository.mapper.JobSyncOffsetMapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.springframework.stereotype.Component; + +@Component +public class DefaultSyncOffsetManager implements SyncOffsetManager { + + private JobSyncOffsetMapper jobSyncOffsetMapper; + + public DefaultSyncOffsetManager(JobSyncOffsetMapper jobSyncOffsetMapper) { + this.jobSyncOffsetMapper = jobSyncOffsetMapper; + } + + @Override + public JobSyncOffset getSyncOffset(SimpleJobContext context) { + LambdaQueryWrapper queryWrapper = buildQueryWrapper(context); + JobSyncOffset syncOffset = jobSyncOffsetMapper.selectOne(queryWrapper); + if (syncOffset != null) { + return syncOffset; + } + initSyncOffset(context); + + return getSyncOffset(context); + } + + @Override + public void initSyncOffset(SimpleJobContext context) { + JobSyncOffset record = new JobSyncOffset(); + record.setGroup(context.getGroup()); + record.setJob(context.getJob()); + context.getSubJob().ifPresent(subJob -> record.setSubJob(subJob)); + record.setSyncOffset(context.getInitialSyncOffset()); + record.setCreator("sync-offset-manager"); + record.setEditor("sync-offset-manager"); + jobSyncOffsetMapper.insert(record); + } + + @Override + public void updateSyncOffset(SimpleJobContext context, String syncOffset) { + JobSyncOffset jobSyncOffset = getSyncOffset(context); + LambdaQueryWrapper queryWrapper = buildQueryWrapper(context); + + JobSyncOffset record = new JobSyncOffset(); + record.setGroup(context.getGroup()); + record.setJob(context.getJob()); + context.getSubJob().ifPresent(subJob -> record.setSubJob(subJob)); + record.setLastSyncOffset(jobSyncOffset.getSyncOffset()); + record.setSyncOffset(syncOffset); + record.setEditor("sync-offset-manager"); + jobSyncOffsetMapper.update(record, queryWrapper); + } + + @Override + public void resetSyncOffset(SimpleJobContext context) { + LambdaQueryWrapper queryWrapper = buildQueryWrapper(context); + jobSyncOffsetMapper.delete(queryWrapper); + initSyncOffset(context); + } + + protected LambdaQueryWrapper buildQueryWrapper(SimpleJobContext context) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(JobSyncOffset.class) + .eq(JobSyncOffset::getGroup, context.getGroup()) + .eq(JobSyncOffset::getJob, context.getJob()); + if (context.getSubJob().isPresent()) { + queryWrapper.eq(JobSyncOffset::getSubJob, context.getSubJob().get()); + } + if (context.getAccount().isPresent()) { + queryWrapper.eq(JobSyncOffset::getAccount, context.getAccount().get()); + } + if (context.getSubAccount().isPresent()) { + queryWrapper.eq(JobSyncOffset::getSubAccount, context.getSubAccount().get()); + } + return queryWrapper; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/FetchResult.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/FetchResult.java new file mode 100644 index 00000000..b5279629 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/FetchResult.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import lombok.Getter; + +@Getter +public class FetchResult { + + private final Request request; + private final Response response; + + public FetchResult(Request request, Response response) { + this.request = request; + this.response = response; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/Job.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/Job.java new file mode 100644 index 00000000..98038a45 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/Job.java @@ -0,0 +1,24 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +public interface Job { + + void process(String param); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/JobContext.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/JobContext.java new file mode 100644 index 00000000..7a80ab1d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/JobContext.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import org.apache.pekko.actor.typed.ActorSystem; + +import java.util.Optional; + +public interface JobContext { + + String getGroup(); + + String getJob(); + + Optional getSubJob(); + + Optional getAccount(); + + Optional getSubAccount(); + + ActorSystem getActorSystem(); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/JobProcessor.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/JobProcessor.java new file mode 100644 index 00000000..b94c1f9f --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/JobProcessor.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.ProcessResult; + +import java.util.List; +import java.util.concurrent.CompletableFuture; + +public interface JobProcessor { + + Context getContext(); + + List map(Root rootTask); + + CompletableFuture process(Sub subTask); + + ProcessResult reduce(ProcessResult result); + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/LockManager.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/LockManager.java new file mode 100644 index 00000000..7a9cff40 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/LockManager.java @@ -0,0 +1,26 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +public interface LockManager { + + boolean lock(JobContext context, RootTask rootTask); + + boolean unlock(JobContext context, RootTask rootTask); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/ParallelJobContext.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/ParallelJobContext.java new file mode 100644 index 00000000..0c0595eb --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/ParallelJobContext.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +public interface ParallelJobContext extends JobContext { + + default int getSubTaskParallelism() { + return 10; + } + + default int getSubTaskBatchSize() { + return 20; + } + + SplitManager getSplitManager(); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/Result.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/Result.java new file mode 100644 index 00000000..61dcfd17 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/Result.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +public interface Result { + + boolean isSuccess(); + + String getMessage(); + + Throwable getThrowable(); + + SubTask getSubTask(); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/RootTask.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/RootTask.java new file mode 100644 index 00000000..cbad8257 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/RootTask.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import java.util.List; + +public interface RootTask { + + Long getIdentifier(); + + List split(Context context); + + Sub build(Long subTaskId, String startSyncOffset, String endSyncOffset); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SplitManager.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SplitManager.java new file mode 100644 index 00000000..bc58aee5 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SplitManager.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.sliew.carp.module.http.sync.framework.util.GradientUtil; +import cn.sliew.carp.module.http.sync.framework.util.SyncOffsetHelper; +import org.apache.pekko.japi.Pair; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.stream.Collectors; + +public interface SplitManager { + + List getGradients(); + + default boolean supportSplit(String startSyncOffset, String endSyncOffset, Duration gradient) { + LocalDateTime startTime = LocalDateTime.parse(startSyncOffset, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)); + LocalDateTime endTime = LocalDateTime.parse(endSyncOffset, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)); + return SyncOffsetHelper.supportSplit(startTime, endTime, gradient); + } + + default List> split(String startSyncOffset, String endSyncOffset, Duration gradient, int total) { + LocalDateTime startTime = LocalDateTime.parse(startSyncOffset, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)); + LocalDateTime endTime = LocalDateTime.parse(endSyncOffset, DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)); + return SyncOffsetHelper.split(startTime, endTime, gradient, total).stream().map(pair -> { + return Pair.create(DateUtil.format(pair.first(), DatePattern.NORM_DATETIME_PATTERN), DateUtil.format(pair.first(), DatePattern.NORM_DATETIME_PATTERN)); + }).collect(Collectors.toUnmodifiableList()); + } + + default Duration getBackoffGradient() { + return GradientUtil.MIN_GRADIENT; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SubTask.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SubTask.java new file mode 100644 index 00000000..fabbf5fe --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SubTask.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.model.internal.ProcessResult; + +import java.util.concurrent.CompletableFuture; + +public interface SubTask { + + Long getIdentifier(); + + Root getRootTask(); + + String getStartSyncOffset(); + + String getEndSyncOffset(); + + CompletableFuture execute(Context context); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SyncOffsetJobContext.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SyncOffsetJobContext.java new file mode 100644 index 00000000..a2ac43e5 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SyncOffsetJobContext.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +public interface SyncOffsetJobContext extends ParallelJobContext { + + SyncOffsetManager getSyncOffsetManager(); + + String getInitialSyncOffset(); + + String getFinalSyncOffset(); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SyncOffsetManager.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SyncOffsetManager.java new file mode 100644 index 00000000..9d4a4aac --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/SyncOffsetManager.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model; + +import cn.sliew.carp.module.http.sync.framework.repository.entity.JobSyncOffset; + +public interface SyncOffsetManager { + + JobSyncOffset getSyncOffset(Context context); + + void initSyncOffset(Context context); + + void updateSyncOffset(Context context, String syncOffset); + + void resetSyncOffset(Context context); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/internal/ProcessResult.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/internal/ProcessResult.java new file mode 100644 index 00000000..65c166f7 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/internal/ProcessResult.java @@ -0,0 +1,83 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model.internal; + +import cn.sliew.carp.module.http.sync.framework.model.Result; +import cn.sliew.carp.module.http.sync.framework.model.SubTask; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ProcessResult implements Result { + + private boolean success = false; + private String message; + private Throwable throwable; + + private SubTask subTask; + + @Override + public boolean isSuccess() { + return success; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public Throwable getThrowable() { + return throwable; + } + + @Override + public SubTask getSubTask() { + return subTask; + } + + public static ProcessResult success(SubTask subTask) { + ProcessResult result = new ProcessResult(); + result.setSuccess(true); + result.setSubTask(subTask); + result.setMessage("success"); + return result; + } + + public static ProcessResult failure(SubTask subTask) { + return failure(subTask, "internal error"); + } + + public static ProcessResult failure(SubTask subTask, String message) { + ProcessResult result = new ProcessResult(); + result.setSuccess(false); + result.setMessage(message); + return result; + } + + public static ProcessResult failure(SubTask subTask, Throwable throwable) { + ProcessResult result = new ProcessResult(); + result.setSuccess(false); + result.setThrowable(throwable); + result.setMessage(throwable.getMessage()); + return result; + } + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/internal/SimpleJobContext.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/internal/SimpleJobContext.java new file mode 100644 index 00000000..435b99ee --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/model/internal/SimpleJobContext.java @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.model.internal; + +import cn.sliew.carp.module.http.sync.framework.model.SplitManager; +import cn.sliew.carp.module.http.sync.framework.model.SyncOffsetJobContext; +import cn.sliew.carp.module.http.sync.framework.model.SyncOffsetManager; +import lombok.Setter; +import org.apache.pekko.actor.typed.ActorSystem; + +import java.util.Optional; + +@Setter +public class SimpleJobContext implements SyncOffsetJobContext { + + private String group; + private String job; + private String subJob; + private String account; + private String subAccount; + + private ActorSystem actorSystem; + + private int subTaskParallelism = 2; + private int subTaskBatchSize = 1; + private SplitManager splitManager; + + private SyncOffsetManager syncOffsetManager; + private String initialSyncOffset; + private String finalSyncOffset; + + @Override + public String getGroup() { + return group; + } + + @Override + public String getJob() { + return job; + } + + @Override + public Optional getSubJob() { + return Optional.ofNullable(subJob); + } + + @Override + public Optional getAccount() { + return Optional.ofNullable(account); + } + + @Override + public Optional getSubAccount() { + return Optional.ofNullable(subAccount); + } + + @Override + public ActorSystem getActorSystem() { + return actorSystem; + } + + @Override + public SplitManager getSplitManager() { + return splitManager; + } + + @Override + public SyncOffsetManager getSyncOffsetManager() { + return syncOffsetManager; + } + + @Override + public String getInitialSyncOffset() { + return initialSyncOffset; + } + + @Override + public String getFinalSyncOffset() { + return finalSyncOffset; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/repository/entity/JobSyncOffset.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/repository/entity/JobSyncOffset.java new file mode 100644 index 00000000..b4c221a3 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/repository/entity/JobSyncOffset.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.repository.entity; + +import cn.sliew.carp.framework.mybatis.entity.BaseAuditDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("job_sync_offset") +public class JobSyncOffset extends BaseAuditDO { + + private static final long serialVersionUID = 1L; + + @TableField("`group`") + private String group; + + @TableField("job") + private String job; + + @TableField("sub_job") + private String subJob; + + @TableField("account") + private String account; + + @TableField("sub_account") + private String subAccount; + + @TableField("last_sync_offset") + private String lastSyncOffset; + + @TableField("sync_offset") + private String syncOffset; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/repository/mapper/JobSyncOffsetMapper.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/repository/mapper/JobSyncOffsetMapper.java new file mode 100644 index 00000000..e10aacff --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/repository/mapper/JobSyncOffsetMapper.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.repository.mapper; + +import cn.sliew.carp.module.http.sync.framework.repository.entity.JobSyncOffset; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springframework.stereotype.Repository; + +@Repository +public interface JobSyncOffsetMapper extends BaseMapper { + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/util/GradientUtil.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/util/GradientUtil.java new file mode 100644 index 00000000..ac6c4f0e --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/util/GradientUtil.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.util; + +import java.time.Duration; +import java.util.Arrays; +import java.util.List; + +public enum GradientUtil { + ; + + public static final Duration MIN_GRADIENT = Duration.ofSeconds(1L); + + public static List getDefaultGradients() { + return Arrays.asList( + Duration.ofMinutes(15L), + Duration.ofMinutes(5L), + Duration.ofMinutes(2L), + Duration.ofMinutes(1L)); + } + + public static List getSparseGradients() { + return Arrays.asList( + Duration.ofDays(1L), + Duration.ofHours(12L), + Duration.ofHours(6L), + Duration.ofHours(3L), + Duration.ofHours(1L), + Duration.ofMinutes(30L) + ); + } + + public static List getMediumGradients() { + return Arrays.asList( + Duration.ofHours(12L), + Duration.ofHours(6L), + Duration.ofHours(3L), + Duration.ofHours(1L) + ); + } + + public static List getSmallGradients() { + return Arrays.asList( + Duration.ofHours(1L), + Duration.ofMinutes(30L) + ); + } + + public static List getDenseGradients() { + return Arrays.asList( + Duration.ofMinutes(1L) + ); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/util/SyncOffsetHelper.java b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/util/SyncOffsetHelper.java new file mode 100644 index 00000000..96551492 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/java/cn/sliew/carp/module/http/sync/framework/util/SyncOffsetHelper.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.framework.util; + +import org.apache.pekko.japi.Pair; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.util.LinkedList; +import java.util.List; + +public enum SyncOffsetHelper { + ; + + public static boolean supportSplit(LocalDateTime startTime, LocalDateTime endTime, Duration gradient) { + LocalDateTime nextStart = startTime.plus(gradient); + return nextStart.isBefore(endTime); + } + + public static List> split(LocalDateTime startTime, LocalDateTime endTime, Duration gradient, int total) { + List> pairs = new LinkedList<>(); + LocalDateTime nextStart = startTime.plus(gradient); + for (int i = 0; i < total; i++) { + if (nextStart.isAfter(endTime)) { + break; + } + pairs.add(new Pair<>(startTime, nextStart)); + startTime = nextStart; + nextStart = startTime.plus(gradient); + } + return pairs; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/resources/cn/sliew/carp/module/http/sync/framework/repository/mapper/JobSyncOffsetMapper.xml b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/resources/cn/sliew/carp/module/http/sync/framework/repository/mapper/JobSyncOffsetMapper.xml new file mode 100644 index 00000000..8893d78a --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-framework/src/main/resources/cn/sliew/carp/module/http/sync/framework/repository/mapper/JobSyncOffsetMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + id, + `group`, job, sub_job, last_sync_offset, sync_offset, account, sub_account, + creator, editor, create_time, update_time + + + diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/pom.xml b/carp-modules/carp-module-http-sync/carp-module-http-job/pom.xml new file mode 100644 index 00000000..d12d5b2d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/pom.xml @@ -0,0 +1,56 @@ + + + + + 4.0.0 + + cn.sliew + carp-module-http-sync + 0.0.13-SNAPSHOT + ../pom.xml + + carp-module-http-job + + + + ${project.parent.groupId} + carp-framework-exception + + + + ${project.parent.groupId} + carp-framework-web + + + + ${project.parent.groupId} + carp-module-http-framework + + + + ${project.parent.groupId} + carp-module-http-remote-feign + + + ${project.parent.groupId} + carp-module-http-remote-jst + + + \ No newline at end of file diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/DataServiceDataSourceConfig.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/DataServiceDataSourceConfig.java new file mode 100644 index 00000000..ab486ae8 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/DataServiceDataSourceConfig.java @@ -0,0 +1,94 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.config; + +import cn.sliew.carp.framework.mybatis.DataSourceConstants; +import cn.sliew.carp.framework.mybatis.config.CarpMybatisConfig; +import com.baomidou.mybatisplus.autoconfigure.MybatisPlusProperties; +import com.baomidou.mybatisplus.core.MybatisConfiguration; +import com.baomidou.mybatisplus.core.config.GlobalConfig; +import com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler; +import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils; +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.ibatis.logging.slf4j.Slf4jImpl; +import org.apache.ibatis.session.SqlSessionFactory; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Autowired; +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.jdbc.datasource.DataSourceTransactionManager; + +import javax.sql.DataSource; + +@Configuration +@MapperScan(sqlSessionFactoryRef = DataServiceDataSourceConfig.SQL_SESSION_FACTORY, + basePackages = {DataServiceDataSourceConfig.MAPPER_MODULE_HTTP_SYNC_JOB_PACKAGE}) +public class DataServiceDataSourceConfig { + + public static final String MAPPER_MODULE_HTTP_SYNC_JOB_PACKAGE = "cn.sliew.carp.module.http.sync.job.repository.mapper"; + + public static final String SQL_SESSION_FACTORY = "dataServiceSqlSessionFactory"; + public static final String DATA_SOURCE_FACTORY = "dataServiceDataSource"; + public static final String TRANSACTION_MANAGER_FACTORY = "dataServiceTransactionManager"; + + @Autowired + private MybatisPlusInterceptor mybatisPlusInterceptor; + + @Primary + @Bean(DataServiceDataSourceConfig.DATA_SOURCE_FACTORY) + @ConfigurationProperties(prefix = "spring.datasource.dataservice") + public DataSource dataServiceDataSource() { + return DataSourceBuilder.create().type(HikariDataSource.class) + .build(); + } + + @Primary + @Bean(DataServiceDataSourceConfig.TRANSACTION_MANAGER_FACTORY) + public DataSourceTransactionManager dataServiceTransactionManager() { + return new DataSourceTransactionManager(dataServiceDataSource()); + } + + @Primary + @Bean(DataServiceDataSourceConfig.SQL_SESSION_FACTORY) + public SqlSessionFactory dataServiceSqlSessionFactory() throws Exception { + MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean(); + GlobalConfig globalConfig = GlobalConfigUtils.defaults(); + globalConfig.setMetaObjectHandler(new CarpMybatisConfig.CarpMetaHandler()); + + MybatisPlusProperties props = new MybatisPlusProperties(); + props.setMapperLocations(new String[]{DataSourceConstants.MAPPER_XML_PATH}); + factoryBean.setMapperLocations(props.resolveMapperLocations()); + + MybatisConfiguration configuration = new MybatisConfiguration(); + configuration.setDefaultEnumTypeHandler(MybatisEnumTypeHandler.class); + configuration.setMapUnderscoreToCamelCase(true); + configuration.setLogImpl(Slf4jImpl.class); + factoryBean.setConfiguration(configuration); + factoryBean.setGlobalConfig(globalConfig); + factoryBean.setDataSource(dataServiceDataSource()); + factoryBean.setPlugins(mybatisPlusInterceptor); + return factoryBean.getObject(); + } + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/HttpSyncFeignConfig.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/HttpSyncFeignConfig.java new file mode 100644 index 00000000..8e1cafed --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/HttpSyncFeignConfig.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.config; + +import cn.sliew.carp.module.http.sync.remote.feign.JacksonQueryMapEncoder; +import feign.Capability; +import feign.QueryMapEncoder; +import feign.codec.Decoder; +import feign.codec.Encoder; +import feign.micrometer.MicrometerCapability; +import feign.okhttp.OkHttpClient; +import io.micrometer.core.instrument.MeterRegistry; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.cloud.openfeign.support.ResponseEntityDecoder; +import org.springframework.cloud.openfeign.support.SpringDecoder; +import org.springframework.cloud.openfeign.support.SpringEncoder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.MediaType; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +@Configuration +@EnableFeignClients(basePackages = { + "cn.sliew.carp.module.http.sync" +}) +public class HttpSyncFeignConfig { + + @Autowired + private MappingJackson2HttpMessageConverter jacksonConverter; + + @Bean + public OkHttpClient okHttpClient() { + return new OkHttpClient(); + } + + @Bean + public Capability capability(MeterRegistry registry) { + return new MicrometerCapability(registry); + } + + @Bean + public QueryMapEncoder queryMapEncoder() { + return new JacksonQueryMapEncoder(); + } + + @Bean + public Encoder encoder() { + addAdditionalMediaType(); + HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter); + ObjectFactory objectFactory = () -> httpMessageConverters; + return new SpringEncoder(objectFactory); + } + + @Bean + public Decoder decoder() { + addAdditionalMediaType(); + HttpMessageConverters httpMessageConverters = new HttpMessageConverters(jacksonConverter); + ObjectFactory objectFactory = () -> httpMessageConverters; + return new ResponseEntityDecoder(new SpringDecoder(objectFactory)); + } + + private void addAdditionalMediaType() { + List supportedMediaTypes = new LinkedList<>(jacksonConverter.getSupportedMediaTypes()); + supportedMediaTypes.addAll(Arrays.asList(MediaType.TEXT_HTML, MediaType.TEXT_PLAIN)); + jacksonConverter.setSupportedMediaTypes(supportedMediaTypes); + } +} \ No newline at end of file diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/HttpSyncOpenAPIConfig.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/HttpSyncOpenAPIConfig.java new file mode 100644 index 00000000..2283275f --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/config/HttpSyncOpenAPIConfig.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.config; + +import org.springdoc.core.models.GroupedOpenApi; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class HttpSyncOpenAPIConfig { + + @Bean + public GroupedOpenApi carpHttpSyncModuleOpenApi() { + return GroupedOpenApi.builder().group("Http同步模块") + .pathsToMatch("/api/carp/http-sync/**") + .packagesToScan("cn.sliew.carp.module.http.sync").build(); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/controller/job/CarpJstController.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/controller/job/CarpJstController.java new file mode 100644 index 00000000..ca969cf1 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/controller/job/CarpJstController.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.controller.job; + +import cn.sliew.carp.framework.common.security.annotations.AnonymousAccess; +import cn.sliew.carp.framework.web.response.ApiResponseWrapper; +import cn.sliew.carp.module.http.sync.job.jst.order.JstOrderJob; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@AnonymousAccess +@RestController +@ApiResponseWrapper +@RequestMapping("/api/carp/http-sync/job/jst") +@Tag(name = "Http同步管理-聚水潭") +public class CarpJstController { + + @Autowired + private JstOrderJob jstOrderJob; + + @GetMapping("jstOrderJob") + @Operation(summary = "订单", description = "订单") + public void jstOrderJob(@RequestParam("param") String param) { + jstOrderJob.process(param); + } + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JobGroup.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JobGroup.java new file mode 100644 index 00000000..aad50814 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JobGroup.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.enums; + +import lombok.Getter; + +@Getter +public enum JobGroup { + + JST("jst", "聚水潭"), + ; + + private String group; + private String desc; + + JobGroup(String group, String desc) { + this.group = group; + this.desc = desc; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JobType.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JobType.java new file mode 100644 index 00000000..22980948 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JobType.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.enums; + +import lombok.Getter; + +@Getter +public enum JobType { + + NORMAL("normal", "普通任务"), + ; + + private String type; + private String desc; + + JobType(String type, String desc) { + this.type = type; + this.desc = desc; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JstApiEnum.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JstApiEnum.java new file mode 100644 index 00000000..b95ebad2 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JstApiEnum.java @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.enums; + +import lombok.Getter; + +@Getter +public enum JstApiEnum { + + SHOPS_QUERY("shops.query", "店铺查询"), + WMS_PARTNER_QUERY("wms.partner.query", "仓库查询"), + CATEGORY_QUERY("category.query", "商品类目查询"), + LOGISTIC_QUERY("logistic.query", "发货信息查询"), + COMBINE_SKU_QUERY("combine.sku.query", "组合商品查询"), + INVENTORY_COUNT_QUERY("inventory.count.query", "库存盘点查询"), + INVENTORY_QUERY("inventory.query", "库存查询"), + PACK_QUERY("pack.query", "箱及仓位库存查询-按照修改时间查询"), + MALL_ITEM_QUERY("mall.item.query", "普通商品查询(按款查询)"), + PURCHASEIN_QUERY("purchasein.query", "采购入库查询"), + PURCHASEOUT_QUERY("purchaseout.query", "采购退货查询"), + PURCHASE_QUERY("purchase.query", "采购单查询"), + SKUMAP_QUERY("skumap.query", "商品映射查询"), + SKU_QUERY("sku.query", "普通商品资料查询(按sku查询)"), + SUPPLIER_QUERY("supplier.query", "供应商查询"), + AFTERSALE_RECEIVED_QUERY("aftersale.received.query", "实际收货查询"), + ALLOCATE_QUERY("allocate.query", "调拨单查询"), + ORDER_ACTION_QUERY("order.action.query", "订单操作日志查询"), + OTHER_INOUT_QUERY("other.inout.query", "其它出入库查询"), + JUSHUITAN_INOUT_WATER_QUERY("jushuitan.inout.water.query", "进出仓流水"), + JUSHUITAN_TRACKINFO_QUERY("jushuitan.trackinfo.query", "通过唯一码查询物流日志"), + + ORDERS_SINGLE_QUERY("orders.single.query", "订单查询"), + REFUND_SINGLE_QUERY("refund.single.query", "退货退款查询"), + ORDERS_OUT_SIMPLE_QUERY("orders.out.simple.query", "销售出库查询"), + + ORDERS_HISTORY_QUERY("orders.history.query", "历史订单查询"), + REFUND_HISTORY_QUERY("refund.history.query", "历史退货退款查询"), + JUSHUITAN_SALEOUT_HISTORY_QUERY("jushuitan.saleout.history.query", "历史销售出库单查询"), + + JUSHUITAN_ORDER_LIST_QUERY("jushuitan.order.list.query", "聚水潭奇门云订单"), + JUSHUITAN_REFUND_LIST_QUERY("jushuitan.refund.list.query", "聚水潭奇门云售后"), + JUSHUITAN_SALEOUT_LIST_QUERY("jushuitan.saleout.list.query", "聚水潭奇门云销售出库"), + ; + + private String api; + private String desc; + + JstApiEnum(String api, String desc) { + this.api = api; + this.desc = desc; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JstJob.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JstJob.java new file mode 100644 index 00000000..eb505007 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/enums/JstJob.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.enums; + +import lombok.Getter; + +@Getter +public enum JstJob { + + NORMAL_ORDERS_SINGLE_QUERY(JobGroup.JST, JobType.NORMAL, JstApiEnum.ORDERS_SINGLE_QUERY, "订单查询"), + ; + + private JobGroup group; + private JobType type; + private JstApiEnum api; + private String desc; + + JstJob(JobGroup group, JobType type, JstApiEnum api, String desc) { + this.group = group; + this.type = type; + this.api = api; + this.desc = desc; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/AbstractJstJob.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/AbstractJstJob.java new file mode 100644 index 00000000..0b85b3c9 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/AbstractJstJob.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.jst; + +import cn.sliew.carp.module.http.sync.framework.model.AbstractJob; +import cn.sliew.carp.module.http.sync.framework.model.RootTask; +import cn.sliew.carp.module.http.sync.framework.model.SplitManager; +import cn.sliew.carp.module.http.sync.framework.model.SyncOffsetManager; +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import cn.sliew.carp.module.http.sync.job.enums.JstJob; +import cn.sliew.carp.module.http.sync.job.remote.JstRemoteService; +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstAuth; +import cn.sliew.carp.module.http.sync.job.repository.mapper.jst.JstAuthMapper; +import cn.sliew.carp.module.http.sync.job.task.jst.AbstractJstRootTask; +import cn.sliew.milky.common.util.JacksonUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import org.apache.pekko.actor.typed.ActorSystem; +import org.apache.pekko.actor.typed.SpawnProtocol; + +import static cn.sliew.milky.common.check.Ensures.checkState; + +public abstract class AbstractJstJob extends AbstractJob { + + protected final JstRemoteService jstRemoteService; + private final JstAuthMapper jstAuthMapper; + + public AbstractJstJob(ActorSystem actorSystem, SyncOffsetManager syncOffsetManager, SplitManager splitManager, JstRemoteService jstRemoteService, JstAuthMapper jstAuthMapper) { + super(actorSystem, syncOffsetManager, splitManager); + this.jstRemoteService = jstRemoteService; + this.jstAuthMapper = jstAuthMapper; + } + + @Override + public String getJobName() { + return String.format("%s.%s.%s", getJstJob().getGroup().getGroup(), getJstJob().getApi().getApi(), getJstJob().getType().getType()); + } + + @Override + protected SimpleJobContext buildJobContext() { + SimpleJobContext jobContext = super.buildJobContext(); + JstJob jstJob = getJstJob(); + jobContext.setGroup(jstJob.getGroup().getGroup()); + jobContext.setJob(jstJob.getApi().getApi()); + jobContext.setSubJob(jstJob.getType().getType()); + return jobContext; + } + + @Override + protected RootTask buildRootTask(Object param) { + JstJobParam jstJobParam = JacksonUtil.parseJsonString((String) param, JstJobParam.class); + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(JstAuth.class) + .eq(JstAuth::getAppKey, jstJobParam.getAppKey()) + .eq(JstAuth::getCompany, jstJobParam.getCompany()); + + JstAuth jstAuth = jstAuthMapper.selectOne(queryWrapper); + checkState(jstAuth != null); + + return buildJstRootTask(jstAuth); + } + + protected abstract JstJob getJstJob(); + + protected abstract AbstractJstRootTask buildJstRootTask(JstAuth jstAuth); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/JstJobParam.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/JstJobParam.java new file mode 100644 index 00000000..90cb66fb --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/JstJobParam.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.jst; + +import lombok.Data; + +@Data +public class JstJobParam { + + private String appKey; + private String company; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/order/JstOrderJob.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/order/JstOrderJob.java new file mode 100644 index 00000000..8ecb7f89 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/jst/order/JstOrderJob.java @@ -0,0 +1,66 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.jst.order; + +import cn.sliew.carp.module.http.sync.framework.model.SplitManager; +import cn.sliew.carp.module.http.sync.framework.model.SyncOffsetManager; +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import cn.sliew.carp.module.http.sync.job.enums.JstJob; +import cn.sliew.carp.module.http.sync.job.jst.AbstractJstJob; +import cn.sliew.carp.module.http.sync.job.remote.JstRemoteService; +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstAuth; +import cn.sliew.carp.module.http.sync.job.repository.mapper.jst.JstAuthMapper; +import cn.sliew.carp.module.http.sync.job.repository.mapper.jst.JstOrderMapper; +import cn.sliew.carp.module.http.sync.job.task.jst.AbstractJstRootTask; +import cn.sliew.carp.module.http.sync.job.task.jst.order.JstOrderRootTask; +import org.apache.pekko.actor.typed.ActorSystem; +import org.apache.pekko.actor.typed.SpawnProtocol; +import org.springframework.stereotype.Component; + +@Component +public class JstOrderJob extends AbstractJstJob { + + private final JstOrderMapper jstOrderMapper; + + public JstOrderJob(ActorSystem actorSystem, SyncOffsetManager syncOffsetManager, SplitManager splitManager, JstRemoteService jstRemoteService, JstAuthMapper jstAuthMapper, JstOrderMapper jstOrderMapper) { + super(actorSystem, syncOffsetManager, splitManager, jstRemoteService, jstAuthMapper); + this.jstOrderMapper = jstOrderMapper; + } + + @Override + protected JstJob getJstJob() { + return JstJob.NORMAL_ORDERS_SINGLE_QUERY; + } + + @Override + protected SimpleJobContext buildJobContext() { + SimpleJobContext jobContext = super.buildJobContext(); + jobContext.setInitialSyncOffset("2024-01-01 00:00:00"); + jobContext.setFinalSyncOffset("2024-11-11 00:00:00"); + + jobContext.setSubTaskParallelism(2); + jobContext.setSubTaskBatchSize(1); + return jobContext; + } + + @Override + protected AbstractJstRootTask buildJstRootTask(JstAuth jstAuth) { + return new JstOrderRootTask(System.currentTimeMillis(), jstRemoteService, jstAuth, jstOrderMapper); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/remote/JstRemoteService.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/remote/JstRemoteService.java new file mode 100644 index 00000000..ba58fb0d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/remote/JstRemoteService.java @@ -0,0 +1,72 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.remote; + +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstAuth; +import cn.sliew.carp.module.http.sync.job.repository.mapper.jst.JstAuthMapper; +import cn.sliew.carp.module.http.sync.job.util.ApiUtil; +import cn.sliew.carp.module.http.sync.remote.jst.api.JstOrderClient; +import cn.sliew.carp.module.http.sync.remote.jst.request.order.OrdersSingleQuery; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.JstOrdersResult; +import cn.sliew.milky.common.util.JacksonUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.google.common.base.Joiner; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +@Service +public class JstRemoteService { + + private URI uri = URI.create("https://api.jushuitan.com/"); + + @Autowired + private JstAuthMapper jstAuthMapper; + @Autowired + private JstOrderClient jstOrderClient; + + private String sign(JstAuth auth, String param) { + Map params = new HashMap(); + params.put("app_key", auth.getAppKey()); + params.put("access_token", auth.getAccessToken()); + params.put("timestamp", String.valueOf(System.currentTimeMillis() / 1000L)); + params.put("version", "2"); + params.put("charset", "utf-8"); + params.put("biz", param); + String sign = ApiUtil.getSign(auth.getAppSecret(), params); + params.put("sign", sign); + return Joiner.on("&").withKeyValueSeparator("=").join(params); + } + + private JstAuth getAuth(String appKey, String company) { + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(JstAuth.class) + .eq(JstAuth::getAppKey, appKey) + .eq(JstAuth::getCompany, company); + return jstAuthMapper.selectOne(queryWrapper); + } + + public JstNewResult getOrders(JstAuth auth, OrdersSingleQuery query) { + return jstOrderClient.getOrders(uri, sign(auth, JacksonUtil.toJsonString(query))); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/BaseSyncMeta.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/BaseSyncMeta.java new file mode 100644 index 00000000..e2aace44 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/BaseSyncMeta.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.repository.entity; + +import cn.sliew.carp.framework.mybatis.entity.BaseAuditDO; +import com.baomidou.mybatisplus.annotation.TableField; +import lombok.Data; + +import java.util.Date; + +@Data +public class BaseSyncMeta extends BaseAuditDO { + + @TableField("sync_start_time") + private Date syncStartTime; + + @TableField("sync_end_time") + private Date syncEndTime; + + @TableField("sync_page_index") + private Integer syncPageIndex; + + @TableField("sync_page_size") + private Integer syncPageSize; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/jst/JstAuth.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/jst/JstAuth.java new file mode 100644 index 00000000..c49bda39 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/jst/JstAuth.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.repository.entity.jst; + +import cn.sliew.carp.framework.mybatis.entity.BaseAuditDO; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("jst_auth") +public class JstAuth extends BaseAuditDO { + + private static final long serialVersionUID = 1L; + + @TableField("app_key") + private String appKey; + + @TableField("app_secret") + private String appSecret; + + @TableField("company") + private String company; + + @TableField("access_token") + private String accessToken; + + @TableField("refresh_token") + private String refreshToken; + + @TableField("expires_in") + private Long expiresIn; + + @TableField("expires_date") + private Date expiresDate; + + @TableField("scope") + private String scope; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/jst/JstOrder.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/jst/JstOrder.java new file mode 100644 index 00000000..e68fe783 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/entity/jst/JstOrder.java @@ -0,0 +1,309 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.repository.entity.jst; + +import cn.sliew.carp.module.http.sync.job.repository.entity.BaseSyncMeta; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.util.Date; + +@Data +@TableName("jst_order") +public class JstOrder extends BaseSyncMeta { + + private static final long serialVersionUID = 1L; + + @TableField("app_key") + private String appKey; + + @TableField("company") + private String company; + + @TableField("is_cod") + private String isCod; + + @TableField("l_id") + private String lId; + + @TableField("send_date") + private Date sendDate; + + @TableField("pay_date") + private Date payDate; + + @TableField("freight") + private String freight; + + @TableField("receiver_address") + private String receiverAddress; + + @TableField("receiver_district") + private String receiverDistrict; + + @TableField("wms_co_id") + private String wmsCoId; + + @TableField("logistics_company") + private String logisticsCompany; + + @TableField("as_id") + private String asId; + + @TableField("free_amount") + private String freeAmount; + + @TableField("shop_name") + private String shopName; + + @TableField("question_type") + private String questionType; + + @TableField("outer_pay_id") + private String outerPayId; + + @TableField("so_id") + private String soId; + + @TableField("`type`") + private String type; + + @TableField("order_from") + private String orderFrom; + + @TableField("`status`") + private String status; + + @TableField("pay_amount") + private String payAmount; + + @TableField("shop_buyer_id") + private String shopBuyerId; + + @TableField("open_id") + private String openId; + + @TableField("shop_status") + private String shopStatus; + + @TableField("receiver_mobile") + private String receiverMobile; + + @TableField("receiver_phone") + private String receiverPhone; + + @TableField("order_date") + private Date orderDate; + + @TableField("question_desc") + private String questionDesc; + + @TableField("receiver_city") + private String receiverCity; + + @TableField("receiver_state") + private String receiverState; + + @TableField("receiver_name") + private String receiverName; + + @TableField("o_id") + private Long oId; + + @TableField("shop_id") + private Long shopId; + + @TableField("co_id") + private Long coId; + + @TableField("remark") + private String remark; + + @TableField("drp_co_id_from") + private String drpCoIdFrom; + + @TableField("modified") + private Date modified; + + @TableField("labels") + private String labels; + + @TableField("paid_amount") + private String paidAmount; + + @TableField("currency") + private String currency; + + @TableField("buyer_message") + private String buyerMessage; + + @TableField("lc_id") + private String lcId; + + @TableField("invoice_title") + private String invoiceTitle; + + @TableField("invoice_type") + private String invoiceType; + + @TableField("buyer_tax_no") + private String buyerTaxNo; + + @TableField("creator_name") + private String creatorName; + + @TableField("plan_delivery_date") + private Date planDeliveryDate; + + @TableField("node") + private String node; + + @TableField("receiver_town") + private String receiverTown; + + @TableField("drp_co_id_to") + private String drpCoIdTo; + + @TableField("shop_site") + private String shopSite; + + @TableField("un_lid") + private String unLid; + + @TableField("end_time") + private Date endTime; + + @TableField("receiver_country") + private String receiverCountry; + + @TableField("receiver_zip") + private String receiverZip; + + @TableField("seller_flag") + private Integer sellerFlag; + + @TableField("receiver_email") + private String receiverEmail; + + @TableField("referrer_id") + private String referrerId; + + @TableField("referrer_name") + private String referrerName; + + @TableField("created") + private String created; + + @TableField("pays") + private String pays; + + @TableField("items") + private String items; + + @TableField("skus") + private String skus; + + @TableField("f_weight") + private String fWeight; + + @TableField("weight") + private String weight; + + @TableField("ts") + private Long ts; + + @TableField("buyer_id") + private String buyerId; + + @TableField("buyer_paid_amount") + private String buyerPaidAmount; + + @TableField("seller_income_amount") + private String sellerIncomeAmount; + + @TableField("chosen_channel") + private String chosenChannel; + + @TableField("link_o_id") + private String linkOId; + + @TableField("merge_so_id") + private String mergeSoId; + + @TableField("shipment") + private String shipment; + + @TableField("sign_time") + private String signTime; + + @TableField("cb_finances") + private String cbFinances; + + @TableField("f_freight") + private String fFreight; + + @TableField("batch_id") + private String batchId; + + @TableField("produced_date") + private String producedDate; + + @TableField("tem_ext_data") + private String temExtData; + + @TableField("discount_rate") + private String discountRate; + + @TableField("tag") + private String tag; + + @TableField("amount") + private String amount; + + @TableField("is_split") + private String isSplit; + + @TableField("is_merge") + private String isMerge; + + @TableField("glasses") + private String glasses; + + @TableField("outer_as_id") + private String outerAsId; + + @TableField("outer_so_id") + private String outerSoId; + + @TableField("__raw_so_ids__") + private String rawSoIds; + + @TableField("ext_datas") + private String extDatas; + + @TableField("raw_so_id") + private String rawSoId; + + @TableField("drp_from") + private String drpFrom; + + @TableField("drp_to") + private String drpTo; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstAuthMapper.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstAuthMapper.java new file mode 100644 index 00000000..f2b060dd --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstAuthMapper.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.repository.mapper.jst; + +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstAuth; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springframework.stereotype.Repository; + +@Repository +public interface JstAuthMapper extends BaseMapper { + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstOrderMapper.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstOrderMapper.java new file mode 100644 index 00000000..5badd205 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstOrderMapper.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.repository.mapper.jst; + +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstOrder; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.springframework.stereotype.Repository; + +@Repository +public interface JstOrderMapper extends BaseMapper { + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/AbstractJstRootTask.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/AbstractJstRootTask.java new file mode 100644 index 00000000..cd4ec925 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/AbstractJstRootTask.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.task.jst; + +import cn.sliew.carp.module.http.sync.framework.model.AbstractRootTask; +import cn.sliew.carp.module.http.sync.job.remote.JstRemoteService; +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstAuth; +import lombok.Getter; + +@Getter +public abstract class AbstractJstRootTask extends AbstractRootTask { + + private JstRemoteService jstRemoteService; + private JstAuth jstAuth; + + public AbstractJstRootTask(Long rootTaskId, JstRemoteService jstRemoteService, JstAuth jstAuth) { + super(rootTaskId); + this.jstRemoteService = jstRemoteService; + this.jstAuth = jstAuth; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/AbstractJstSubTask.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/AbstractJstSubTask.java new file mode 100644 index 00000000..baec8cde --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/AbstractJstSubTask.java @@ -0,0 +1,28 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.task.jst; + +import cn.sliew.carp.module.http.sync.framework.model.AbstractSubTask; + +public abstract class AbstractJstSubTask extends AbstractSubTask { + + public AbstractJstSubTask(Long subTaskId, Root rootTask, String startSyncOffset, String endSyncOffset) { + super(subTaskId, rootTask, startSyncOffset, endSyncOffset); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/order/JstOrderRootTask.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/order/JstOrderRootTask.java new file mode 100644 index 00000000..db703415 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/order/JstOrderRootTask.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.task.jst.order; + +import cn.sliew.carp.module.http.sync.job.remote.JstRemoteService; +import cn.sliew.carp.module.http.sync.job.repository.mapper.jst.JstOrderMapper; +import cn.sliew.carp.module.http.sync.job.task.jst.AbstractJstRootTask; +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstAuth; + +public class JstOrderRootTask extends AbstractJstRootTask { + + private JstOrderMapper jstOrderMapper; + + public JstOrderRootTask(Long rootTaskId, JstRemoteService jstRemoteService, JstAuth jstAuth, JstOrderMapper jstOrderMapper) { + super(rootTaskId, jstRemoteService, jstAuth); + this.jstOrderMapper = jstOrderMapper; + } + + @Override + public JstOrderSubTask build(Long subTaskId, String startSyncOffset, String endSyncOffset) { + return new JstOrderSubTask(subTaskId, this, startSyncOffset, endSyncOffset, getJstRemoteService(), jstOrderMapper); + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/order/JstOrderSubTask.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/order/JstOrderSubTask.java new file mode 100644 index 00000000..ea82bef9 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/order/JstOrderSubTask.java @@ -0,0 +1,150 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.task.jst.order; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.date.DatePattern; +import cn.hutool.core.date.DateUtil; +import cn.sliew.carp.framework.exception.SliewException; +import cn.sliew.carp.module.http.sync.framework.model.FetchResult; +import cn.sliew.carp.module.http.sync.framework.model.internal.SimpleJobContext; +import cn.sliew.carp.module.http.sync.job.remote.JstRemoteService; +import cn.sliew.carp.module.http.sync.job.repository.entity.jst.JstOrder; +import cn.sliew.carp.module.http.sync.job.repository.mapper.jst.JstOrderMapper; +import cn.sliew.carp.module.http.sync.job.task.jst.AbstractJstSubTask; +import cn.sliew.carp.module.http.sync.job.task.jst.util.JstResultWrapper; +import cn.sliew.carp.module.http.sync.job.task.jst.util.JstUtil; +import cn.sliew.carp.module.http.sync.remote.jst.request.order.OrdersSingleQuery; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.JstOrdersResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.OrdersSingleDO; +import cn.sliew.milky.common.util.JacksonUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.collections4.CollectionUtils; +import org.apache.pekko.japi.Pair; +import org.apache.pekko.stream.javadsl.Source; + +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; + +@Slf4j +public class JstOrderSubTask extends AbstractJstSubTask { + + private final JstRemoteService remoteService; + private final JstOrderMapper jstOrderMapper; + + public JstOrderSubTask(Long subTaskId, JstOrderRootTask rootTask, String startSyncOffset, String endSyncOffset, JstRemoteService remoteService, JstOrderMapper jstOrderMapper) { + super(subTaskId, rootTask, startSyncOffset, endSyncOffset); + this.remoteService = remoteService; + this.jstOrderMapper = jstOrderMapper; + } + + @Override + protected Source, ?> fetch(SimpleJobContext context) { + OrdersSingleQuery first = buildFirstRequest(context); + return Source.unfoldAsync(first, key -> { + if (key == null) { + return CompletableFuture.completedFuture(Optional.empty()); + } + JstOrdersResult jstOrdersResult = requestRemote(context, key); + FetchResult fetchResult = new FetchResult<>(key, jstOrdersResult); + if (jstOrdersResult.isHasNext()) { + OrdersSingleQuery next = BeanUtil.copyProperties(key, OrdersSingleQuery.class); + next.setPageIndex(key.getPageIndex() + 1); + return CompletableFuture.completedFuture(Optional.of(Pair.create(next, fetchResult))); + } + return CompletableFuture.completedFuture(Optional.of(Pair.create(null, fetchResult))); + }); + } + + @Override + protected OrdersSingleQuery buildFirstRequest(SimpleJobContext context) { + OrdersSingleQuery query = new OrdersSingleQuery(); + query.setModifiedBegin(getStartSyncOffset()); + query.setModifiedEnd(getEndSyncOffset()); + query.setPageIndex(1); + query.setPageSize(50); + return query; + } + + @Override + protected JstOrdersResult requestRemote(SimpleJobContext context, OrdersSingleQuery request) { + JstNewResult jstNewResult = remoteService.getOrders(getRootTask().getJstAuth(), request); + if (jstNewResult.isSuccess()) { + JstOrdersResult jstResult = jstNewResult.getData(); + JstResultWrapper jstResultWrapper = JstUtil.convertResult(jstResult, OrdersSingleDO::getOId); + log.debug("请求聚水潭接口返回结果, {}, request: {}, result: {}", + context.getGroup(), JacksonUtil.toJsonString(request), JacksonUtil.toJsonString(jstResultWrapper)); + return jstResult; + } + log.error("请求聚水潭接口失败! method: {}, code: {}, msg: {}, query: {}", + context.getGroup(), jstNewResult.getCode(), jstNewResult.getMsg(), JacksonUtil.toJsonString(request)); + throw new SliewException(Objects.toString(jstNewResult.getCode()), jstNewResult.getMsg()); + } + + @Override + protected void persistData(SimpleJobContext context, OrdersSingleQuery request, JstOrdersResult response) { + if (CollectionUtils.isEmpty(response.getDatas())) { + return; + } + response.getDatas().forEach(data -> upsert(request, data)); + } + + private void upsert(OrdersSingleQuery request, OrdersSingleDO data) { + JstOrder record = convert(request, data); + + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(JstOrder.class) + .eq(JstOrder::getAppKey, record.getAppKey()) + .eq(JstOrder::getCompany, record.getCompany()) + .eq(JstOrder::getOId, record.getOId()) + .select(JstOrder::getId); + + JstOrder jstOrder = jstOrderMapper.selectOne(queryWrapper); + if (jstOrder != null) { + record.setId(jstOrder.getId()); + record.setEditor("sync-task"); + jstOrderMapper.updateById(record); + } else { + record.setCreator("sync-task"); + record.setEditor("sync-task"); + jstOrderMapper.insert(record); + } + } + + private JstOrder convert(OrdersSingleQuery request, OrdersSingleDO data) { + JstOrder record = BeanUtil.copyProperties(data, JstOrder.class); + if (CollectionUtils.isEmpty(data.getItems()) == false) { + record.setItems(JacksonUtil.toJsonString(data.getItems())); + } + if (org.springframework.util.CollectionUtils.isEmpty(data.getPays()) == false) { + record.setPays(JacksonUtil.toJsonString(data.getPays())); + } + if (org.springframework.util.CollectionUtils.isEmpty(data.getRawSoIds()) == false) { + record.setRawSoIds(JacksonUtil.toJsonString(data.getRawSoIds())); + } + record.setSyncStartTime(DateUtil.parse(request.getModifiedBegin(), DatePattern.NORM_DATETIME_PATTERN).toJdkDate()); + record.setSyncEndTime(DateUtil.parse(request.getModifiedEnd(), DatePattern.NORM_DATETIME_PATTERN).toJdkDate()); + record.setSyncPageIndex(request.getPageIndex()); + record.setSyncPageSize(request.getPageSize()); + return record; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/util/JstResultWrapper.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/util/JstResultWrapper.java new file mode 100644 index 00000000..d67fb65d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/util/JstResultWrapper.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.task.jst.util; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import org.springframework.lang.Nullable; + +import java.util.List; + +@Getter +@Setter +public class JstResultWrapper { + + @JsonProperty("page_index") + private int pageIndex; + + @JsonProperty("page_size") + private int pageSize; + + @Nullable + @JsonProperty("data_count") + private int dataCount; + + @Nullable + @JsonProperty("page_count") + private int pageCount; + + @JsonProperty("has_next") + private boolean hasNext; + + @JsonProperty("issuccess") + private boolean issuccess; + + private int code; + private String msg; + private List datas; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/util/JstUtil.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/util/JstUtil.java new file mode 100644 index 00000000..34ea1624 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/task/jst/util/JstUtil.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.task.jst.util; + +import cn.hutool.core.bean.BeanUtil; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import org.springframework.util.CollectionUtils; + +import java.util.function.Function; +import java.util.stream.Collectors; + +public enum JstUtil { + ; + + public static JstResultWrapper convertResult(JstResult jstResult, Function convert) { + JstResultWrapper jstResultWrapper = BeanUtil.copyProperties(jstResult, JstResultWrapper.class); + if (CollectionUtils.isEmpty(jstResult.getDatas()) == false) { + jstResultWrapper.setDatas(jstResult.getDatas().stream().map(convert).collect(Collectors.toList())); + } + return jstResultWrapper; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/util/ApiUtil.java b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/util/ApiUtil.java new file mode 100644 index 00000000..de348dd3 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/java/cn/sliew/carp/module/http/sync/job/util/ApiUtil.java @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.job.util; + +import org.apache.commons.lang3.StringUtils; + +import java.security.MessageDigest; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +/** + * 聚水潭开放平台下载 jar 包内的工具类,copy 过来的 + */ +public enum ApiUtil { + ; + + public static String getSign(String signKey, Map params) { + String sortedStr = getSortedParamStr(params); + String paraStr = signKey + sortedStr; + return createSign(paraStr); + } + + public static String getSortedParamStr(Map params) { + Set sortedParams = new TreeSet(params.keySet()); + StringBuilder stringBuilder = new StringBuilder(); + for (String key : sortedParams) { + if (!"sign".equalsIgnoreCase(key)) { + String value = params.get(key); + if (StringUtils.isNotBlank(value)) { + stringBuilder.append(key).append(value); + } + } + } + return stringBuilder.toString(); + } + + public static String createSign(String str) { + if (str != null && str.length() != 0) { + char[] hexDigits = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + + try { + MessageDigest mdTemp = MessageDigest.getInstance("MD5"); + mdTemp.update(str.getBytes("UTF-8")); + byte[] md = mdTemp.digest(); + int j = md.length; + char[] buf = new char[j * 2]; + int k = 0; + + for (int i = 0; i < j; ++i) { + byte byte0 = md[i]; + buf[k++] = hexDigits[byte0 >>> 4 & 15]; + buf[k++] = hexDigits[byte0 & 15]; + } + + return new String(buf); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + return null; + } + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/resources/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstAuthMapper.xml b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/resources/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstAuthMapper.xml new file mode 100644 index 00000000..07b0051c --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/resources/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstAuthMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + id, + creator, + create_time, + editor, + update_time, + app_key, app_secret, company, access_token, refresh_token, expires_in, expires_date, scope + + + diff --git a/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/resources/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstOrderMapper.xml b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/resources/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstOrderMapper.xml new file mode 100644 index 00000000..e7149171 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-job/src/main/resources/cn/sliew/carp/module/http/sync/job/repository/mapper/jst/JstOrderMapper.xml @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, + creator, + create_time, + editor, + update_time, + app_key, company, is_cod, l_id, send_date, pay_date, freight, receiver_address, receiver_district, wms_co_id, logistics_company, as_id, free_amount, shop_name, question_type, outer_pay_id, so_id, `type`, order_from, `status`, pay_amount, shop_buyer_id, open_id, shop_status, receiver_mobile, receiver_phone, order_date, question_desc, receiver_city, receiver_state, receiver_name, o_id, shop_id, co_id, remark, drp_co_id_from, modified, labels, paid_amount, currency, buyer_message, lc_id, invoice_title, invoice_type, buyer_tax_no, creator_name, plan_delivery_date, node, receiver_town, drp_co_id_to, shop_site, un_lid, end_time, receiver_country, receiver_zip, seller_flag, receiver_email, referrer_id, referrer_name, created, pays, items, skus, f_weight, weight, ts, buyer_id, buyer_paid_amount, seller_income_amount, chosen_channel, link_o_id, merge_so_id, shipment, sign_time, cb_finances, f_freight, batch_id, produced_date, tem_ext_data, discount_rate, tag, amount, is_split, is_merge, glasses, outer_as_id, outer_so_id, __raw_so_ids__, ext_datas, raw_so_id, drp_from, drp_to, sync_start_time, sync_end_time, sync_page_index, sync_page_size + + + diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-feign/pom.xml b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-feign/pom.xml new file mode 100644 index 00000000..e44854da --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-feign/pom.xml @@ -0,0 +1,61 @@ + + + + + 4.0.0 + + cn.sliew + carp-module-http-remote + 0.0.13-SNAPSHOT + ../pom.xml + + carp-module-http-remote-feign + + + + ${project.parent.groupId} + carp-framework-common + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + io.github.openfeign + feign-okhttp + + + io.github.openfeign + feign-jackson + + + io.github.openfeign + feign-micrometer + + + + com.fasterxml.jackson.core + jackson-annotations + provided + + + + \ No newline at end of file diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-feign/src/main/java/cn/sliew/carp/module/http/sync/remote/feign/JacksonQueryMapEncoder.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-feign/src/main/java/cn/sliew/carp/module/http/sync/remote/feign/JacksonQueryMapEncoder.java new file mode 100644 index 00000000..1161ad88 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-feign/src/main/java/cn/sliew/carp/module/http/sync/remote/feign/JacksonQueryMapEncoder.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.feign; + +import cn.sliew.milky.common.util.JacksonUtil; +import feign.QueryMapEncoder; + +import java.util.Map; + +public class JacksonQueryMapEncoder implements QueryMapEncoder { + + @Override + public Map encode(Object o) { + String jsonString = JacksonUtil.toJsonString(o); + return JacksonUtil.parseJsonString(jsonString, Map.class); + } +} \ No newline at end of file diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/pom.xml b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/pom.xml new file mode 100644 index 00000000..58372378 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/pom.xml @@ -0,0 +1,41 @@ + + + + + 4.0.0 + + cn.sliew + carp-module-http-remote + 0.0.13-SNAPSHOT + ../pom.xml + + carp-module-http-remote-jst + + + 0.0.1 + + + + + ${project.parent.groupId} + carp-module-http-remote-feign + + + \ No newline at end of file diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstAuthClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstAuthClient.java new file mode 100644 index 00000000..c83fed66 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstAuthClient.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.auth.JstAccessTokenDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.SpringQueryMap; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; +import java.util.Map; + +@FeignClient(value = "jstAuthClient", url = "EMPTY") +public interface JstAuthClient { + + @PostMapping(value = "/openWeb/auth/getInitToken", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult accessToken(URI uri, @SpringQueryMap Map params); + + @PostMapping(value = "/openWeb/auth/refreshToken", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult refreshToken(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstBaseClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstBaseClient.java new file mode 100644 index 00000000..4b208039 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstBaseClient.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.base.ShopDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.base.WmsPartnerDO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstBaseClient", url = "EMPTY") +public interface JstBaseClient { + + @PostMapping(value = "/open/shops/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getShops(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/wms/partner/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getWmsPartner(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstInventoryClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstInventoryClient.java new file mode 100644 index 00000000..0ede7e04 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstInventoryClient.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.inventory.InventoryCountDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.inventory.JstInventoryResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.inventory.PackDO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstInventoryClient", url = "EMPTY") +public interface JstInventoryClient { + + @PostMapping(value = "/open/pack/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getPack(URI uri, @RequestBody String sign); + + @PostMapping(value = "/open/inventory/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult getInventoryQuery(URI uri, String sign); + + @PostMapping(value = "/open/inventory/count/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getInventoryCount(URI uri, String sign); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstItemClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstItemClient.java new file mode 100644 index 00000000..55947695 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstItemClient.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.item.*; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstItemClient", url = "EMPTY") +public interface JstItemClient { + + @PostMapping(value = "/open/skumap/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getSkumap(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/mall/item/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getMallItem(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/combine/sku/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getCombineSku(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/sku/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getSku(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/category/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getCategoryInfo(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstLogisticClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstLogisticClient.java new file mode 100644 index 00000000..80b4dd52 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstLogisticClient.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.logistics.JstLogisticResult; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstLogisticClient", url = "EMPTY") +public interface JstLogisticClient { + + @PostMapping(value = "/open/logistic/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult getLogisticInfo(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstOrderClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstOrderClient.java new file mode 100644 index 00000000..45d18d7c --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstOrderClient.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.JstOrdersResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.OrderActionDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.OrdersOutSimpleDO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstOrderClient", url = "EMPTY") +public interface JstOrderClient { + + @PostMapping(value = "/open/orders/single/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult getOrders(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/orders/out/simple/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getOrdersOut(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/order/action/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getOrderAction(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstPurchaseClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstPurchaseClient.java new file mode 100644 index 00000000..0571329a --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstPurchaseClient.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.purchase.PurchaseDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.purchase.PurchaseinDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.purchase.PurchaseoutDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.purchase.SupplierDO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstPurchaseClient", url = "EMPTY") +public interface JstPurchaseClient { + + @PostMapping(value = "/open/purchase/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getPurchase(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/purchasein/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getPurchasein(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/purchaseout/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getPurchaseout(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/supplier/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getSupplier(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstRefundClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstRefundClient.java new file mode 100644 index 00000000..1a3d7f91 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstRefundClient.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.refund.RefundSingleDO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstRefundClient", url = "EMPTY") +public interface JstRefundClient { + + @PostMapping(value = "/open/refund/single/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getRefund(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstWmsClient.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstWmsClient.java new file mode 100644 index 00000000..f3ee3552 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/api/JstWmsClient.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.api; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstNewResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.refund.AllocateDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.refund.InoutWaterDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.refund.OtherInoutDO; +import cn.sliew.carp.module.http.sync.remote.jst.response.refund.TrackinfoDO; +import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; + +import java.net.URI; + +@FeignClient(value = "jstWmsClient", url = "EMPTY") +public interface JstWmsClient { + + @PostMapping(value = "/open/allocate/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getAllocate(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/jushuitan/trackinfo/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getTrackinfo(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/jushuitan/inout/water/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getInoutWater(URI uri, @RequestBody String paramStr); + + @PostMapping(value = "/open/other/inout/query", headers = {"Content-Type", "application/x-www-form-urlencoded;charset=utf-8", "Accept", "application/json"}) + JstNewResult> getOtherInout(URI uri, @RequestBody String paramStr); +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/ModifiedTimeQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/ModifiedTimeQuery.java new file mode 100644 index 00000000..21069efe --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/ModifiedTimeQuery.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class ModifiedTimeQuery extends PagedQuery { + + @Schema(description = "修改起始时间,起始时间和 结束时间必须同时存在,时间间隔不能超过七天") + @JsonProperty("modified_begin") + private String modifiedBegin; + + @Schema(description = "修改起始时间,起始时间和 结束时间必须同时存在,时间间隔不能超过七天") + @JsonProperty("modified_end") + private String modifiedEnd; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/PagedQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/PagedQuery.java new file mode 100644 index 00000000..51ca8808 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/PagedQuery.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class PagedQuery { + + @Schema(description = "第几页,从1 开始") + @JsonProperty("page_index") + private int pageIndex = 1; + + @Schema(description = "默认 30,最大不超过 50") + @JsonProperty("page_size") + private int pageSize = 50; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/base/ShopsQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/base/ShopsQuery.java new file mode 100644 index 00000000..fd84cfac --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/base/ShopsQuery.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.base; + +import cn.sliew.carp.module.http.sync.remote.jst.request.PagedQuery; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class ShopsQuery extends PagedQuery { + + /** + * 店铺主账号,不支持模糊查询 + * 请求参数为返回结果中的 short_name 字段,不支持模糊查询,必须完全匹配 + * 如果不传店铺名,则返回全部店铺 + */ + private List nicks; + + private List shopIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/base/WmsPartnerQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/base/WmsPartnerQuery.java new file mode 100644 index 00000000..9eca5080 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/base/WmsPartnerQuery.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.base; + +import cn.sliew.carp.module.http.sync.remote.jst.request.PagedQuery; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class WmsPartnerQuery extends PagedQuery { + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/InventoryCountQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/InventoryCountQuery.java new file mode 100644 index 00000000..4cf17670 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/InventoryCountQuery.java @@ -0,0 +1,41 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.inventory; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class InventoryCountQuery extends ModifiedTimeQuery { + + /** + * 指定盘点单号,多个用逗号分隔,最多50,和时间段不能同时为空 + */ + @JsonProperty("io_ids") + private String ioIds; + + /** + * 状态;WaitConfirm:待确认,Confirmed:生效,Archive:归档,Cancelled:取消,Delete:作废 + */ + @JsonProperty("status") + private String status; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/InventoryQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/InventoryQuery.java new file mode 100644 index 00000000..3cb19c1e --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/InventoryQuery.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.inventory; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class InventoryQuery extends ModifiedTimeQuery { + + /** + * 分仓公司编号,值不传或为0查询所有仓的总库存,其它为指定仓的库存 + */ + @JsonProperty("wms_co_id") + private Integer wmsCoId; + + /** + * 商品编码,多个用逗号分隔,最多20,与修改时间不能同时为空 + */ + @JsonProperty("sku_ids") + private String skuIds; + + /** + * 时间戳,防漏单,如果用ts查询不需要传时间查询条件 + */ + @JsonProperty("ts") + private Long ts; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/PackQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/PackQuery.java new file mode 100644 index 00000000..05c65c70 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/inventory/PackQuery.java @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.inventory; + +import cn.sliew.carp.module.http.sync.remote.jst.request.PagedQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class PackQuery extends PagedQuery { + + /** + * 商品编码列表,最多20个sku + */ + @JsonProperty("sku_ids") + private List skuIds; + + /** + * 仓库编号 + */ + @JsonProperty("wms_co_id") + private Integer wmsCoId; + + /** + * 类型,Bin=仓位库存,DefaultPack=暂存位 Pack=装箱库存 + */ + @JsonProperty("pack_type") + private String packType; + + /** + * 查询起始时间;时间条件与商品编码不能同时为空 + */ + @JsonProperty("start_time") + private String modifiedBegin; + + /** + * 查询截止时间,时间间 隔最大1天 + */ + @JsonProperty("end_time") + private String modifiedEnd; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/CategoryQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/CategoryQuery.java new file mode 100644 index 00000000..ed54ba86 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/CategoryQuery.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.item; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class CategoryQuery extends ModifiedTimeQuery { + + /** + * 类目id集合 + */ + @JsonProperty("c_ids") + private List cIds; + + /** + * 父级类目id集合 + */ + @JsonProperty("parent_c_ids") + private List parentCIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/CombineSkuQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/CombineSkuQuery.java new file mode 100644 index 00000000..468c5506 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/CombineSkuQuery.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.item; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CombineSkuQuery extends ModifiedTimeQuery { + + /** + * 商品编码列表,字符串形式,按逗号分隔 + */ + @JsonProperty("sku_ids") + private String skuIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/MallItemQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/MallItemQuery.java new file mode 100644 index 00000000..c9474108 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/MallItemQuery.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.item; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class MallItemQuery extends ModifiedTimeQuery { + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/SkuQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/SkuQuery.java new file mode 100644 index 00000000..9a120609 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/SkuQuery.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.item; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class SkuQuery extends ModifiedTimeQuery { + + /** + * 商品编码列表,字符串形式,按逗号分隔 + */ + @JsonProperty("sku_ids") + private String skuIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/SkumapQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/SkumapQuery.java new file mode 100644 index 00000000..b6339c29 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/item/SkumapQuery.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.item; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class SkumapQuery extends ModifiedTimeQuery { + + /** + * 商品编码列表,字符串形式,按逗号分隔 + */ + @JsonProperty("sku_ids") + private String skuIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/logistics/LogisticQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/logistics/LogisticQuery.java new file mode 100644 index 00000000..c48306fd --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/logistics/LogisticQuery.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.logistics; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class LogisticQuery extends ModifiedTimeQuery { + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Integer shopId; + + /** + * 平台订单编号,最多20 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 日期类型,默认发货时间,0=修改时间,1=制单日期,2=订单日期,3=发货时间 + */ + @JsonProperty("date_type") + private Integer dateType = 0; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/logistics/LogisticscompanyQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/logistics/LogisticscompanyQuery.java new file mode 100644 index 00000000..aba8bffe --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/logistics/LogisticscompanyQuery.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.logistics; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class LogisticscompanyQuery extends ModifiedTimeQuery { + + /** + * 公司编号,该值存在时查询对应公司或分仓下的启用的物流公司信息,否则查询系统内所有的物流公司信息 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/AftersaleReceivedQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/AftersaleReceivedQuery.java new file mode 100644 index 00000000..35fa41d2 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/AftersaleReceivedQuery.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.order; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class AftersaleReceivedQuery extends ModifiedTimeQuery { + + /** + * 外部订单号列表 + */ + @JsonProperty("so_ids") + private List soIds; + /** + * ERP 内部订单号,唯一 + */ + @JsonProperty("o_ids") + private List oIds; + + /** + * 退货店铺 + */ + @JsonProperty("shop_id") + private String shopId; + + /** + * 日期类型,0:修改时间,1:创建日期,2:订单日期,4:实际出/入库时间 + */ + @JsonProperty("date_type") + private Integer dateType = 0; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrderActionQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrderActionQuery.java new file mode 100644 index 00000000..db348358 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrderActionQuery.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.order; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class OrderActionQuery extends ModifiedTimeQuery { + + /** + * 内部订单号 + */ + @JsonProperty("o_id") + private Long oId; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrdersOutSimpleQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrdersOutSimpleQuery.java new file mode 100644 index 00000000..012f20f6 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrdersOutSimpleQuery.java @@ -0,0 +1,115 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.order; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class OrdersOutSimpleQuery extends ModifiedTimeQuery { + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Integer shopId; + + /** + * shop_id为0且is_offline_shop为true查询线下店铺单据 + */ + @JsonProperty("is_offline_shop") + private Boolean isOfflineShop; + + /** + * 指定线上订单号,和时间段不能同时为空 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 单据状态: WaitConfirm=待出库; Confirmed=已出库; Cancelled=作废 + */ + @JsonProperty("status") + private String status; + + /** + * 出库仓编号 + */ + @JsonProperty("wms_co_id") + private Integer wmsCoId; + + /** + * 内部单号最大50条;与时间条件不能同时为空 + */ + @JsonProperty("o_ids") + private List oIds; + + /** + * 物流单号;不超过20条 + */ + @JsonProperty("l_ids") + private List lIds; + + /** + * 拣货批次号;不超过50条 与时间条件不能同时为空 + */ + @JsonProperty("wave_ids") + private List waveIds; + + /** + * 时间戳,sql server中的行版本号,该字段查询防止分页过程中漏单 + */ + @JsonProperty("start_ts") + private Long startTs; + + /** + * 是否查询总条数默认true,如果使用start_ts查询,该值传false否则影响查询效率 + */ + @JsonProperty("is_get_total") + private Boolean isGetTotal; + + /** + * 出库单号列表,最大50 + */ + @JsonProperty("io_ids") + private List ioIds; + + /** + * 货主编码 + */ + @JsonProperty("owner_co_id") + private Long ownerCoId; + + /** + * 是否获取跨境财务信息 + */ + @JsonProperty("is_get_cbfinance") + private Boolean isGetCbfinance; + + /** + * 时间类型 0:修改时间modified,1:创建时间created,2:出库时间io_date;默认0 + */ + @JsonProperty("date_type") + private Integer dateType = 0; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrdersSingleQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrdersSingleQuery.java new file mode 100644 index 00000000..2c1cc6fd --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/order/OrdersSingleQuery.java @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.order; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class OrdersSingleQuery extends ModifiedTimeQuery { + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Integer shopId; + + /** + * 线上单号,最大限制20条 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 待付款:WaitPay;发货中:Delivering;被合并:Merged;异常:Question;被拆分:Split;等供销商|外仓发货:WaitOuterSent;已付款待审核:WaitConfirm;已客审待财审:WaitFConfirm;已发货:Sent;取消:Cancelled + */ + @JsonProperty("status") + private String status; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseQuery.java new file mode 100644 index 00000000..19be1d4d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseQuery.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.purchase; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class PurchaseQuery extends ModifiedTimeQuery { + + /** + * 外部订单号列表 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 采购单号列表 + */ + @JsonProperty("po_ids") + private List poIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseinQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseinQuery.java new file mode 100644 index 00000000..d637283f --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseinQuery.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.purchase; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class PurchaseinQuery extends ModifiedTimeQuery { + + /** + * 采购单号列表,与修改时间不能同时为空.采购单号最大不能超过30条 + */ + @JsonProperty("po_ids") + private List poIds; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseoutQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseoutQuery.java new file mode 100644 index 00000000..00066806 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/PurchaseoutQuery.java @@ -0,0 +1,42 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.purchase; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class PurchaseoutQuery extends ModifiedTimeQuery { + + /** + * 指定线上订单号,和时间段不能同时为空 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 单据状态,Confirmed=生效,WaitConfirm待审核,Creating=草拟,Archive=归档,Cancelled=作废 + */ + private String status; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/SupplierQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/SupplierQuery.java new file mode 100644 index 00000000..71fa85f7 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/purchase/SupplierQuery.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.purchase; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class SupplierQuery extends ModifiedTimeQuery { + + /** + * 供应商编码 + */ + @JsonProperty("supplier_codes") + private List supplierCodes; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/refund/RefundSingleQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/refund/RefundSingleQuery.java new file mode 100644 index 00000000..36b50929 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/refund/RefundSingleQuery.java @@ -0,0 +1,103 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.refund; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class RefundSingleQuery extends ModifiedTimeQuery { + + /** + * 指定线上订单号,和时间段不能同时为空 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 指定买家账号,最多50 + */ + @JsonProperty("shop_buyer_ids") + private List shopBuyerIds; + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Integer shopId; + + /** + * shop_id为0且is_offline_shop为true查询线下店铺单据 + */ + @JsonProperty("is_offline_shop") + private Boolean isOfflineShop; + + /** + * 指定内部单号,和时间段不能同时为空 + */ + @JsonProperty("o_ids") + private List oIds; + + /** + * 指定售后单号,和时间段不能同时为空 + */ + @JsonProperty("as_ids") + private List asIds; + + /** + * 售后单状态(WaitConfirm:待确认,Confirmed:已确认,Cancelled:作废,Merged:被合并) + */ + @JsonProperty("status") + private String status; + + /** + * 时间戳,sql server中的行版本号,该字段查询防止分页过程中漏单 + */ + @JsonProperty("start_ts") + private Long startTs; + + /** + * 是否查询总条数默认true,如果使用start_ts查询,该值传false否则影响查询效率 + */ + @JsonProperty("is_get_total") + private Boolean isGetTotal; + + /** + * 货物状态(BUYER_NOT_RECEIVED:买家未收到货,BUYER_RECEIVED:买家已收到货,BUYER_RETURNED_GOODS:买家已退货,SELLER_RECEIVED:卖家已收到退货) + */ + @JsonProperty("good_status") + private String goodStatus; + + /** + * 售后类型,普通退货,其它,拒收退货,仅退款,投诉,补发,换货,维修 + */ + @JsonProperty("type") + private String type; + + /** + * 货主编码 + */ + @JsonProperty("owner_co_id") + private Long ownerCoId; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/AllocateQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/AllocateQuery.java new file mode 100644 index 00000000..68c14d27 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/AllocateQuery.java @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.wms; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class AllocateQuery extends ModifiedTimeQuery { + + /** + * 指定线上订单号,和时间段不能同时为空 + */ + @JsonProperty("so_ids") + private List soIds; + + /** + * 调拨单号 + */ + @JsonProperty("io_ids") + private List ioIds; + + /** + * 调拨类型(调拨出,调拨入) + */ + @JsonProperty("type") + private String type; + + /** + * 0:修改时间,modified。 2:出入库时间 io_date,未传入时默认为0 + */ + @JsonProperty("date_type") + private Integer dateType; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/InoutWaterQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/InoutWaterQuery.java new file mode 100644 index 00000000..7c4d70ef --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/InoutWaterQuery.java @@ -0,0 +1,48 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.wms; + +import cn.sliew.carp.module.http.sync.remote.jst.request.PagedQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class InoutWaterQuery extends PagedQuery { + + @Schema(description = "开始时间") + @JsonProperty("start_time") + private String startTime; + + @Schema(description = "结束时间") + @JsonProperty("end_time") + private String endEime; + + @Schema(description = "默认0,0=修改时间;1=制单日期;2=出入库时间") + @JsonProperty("date_type") + private Integer dateType; + + @Schema(description = "单据类型,采购进仓,采购退货,调拨出,调拨入,加工出仓,加工进仓,盘点,销售出仓,销售退货,其它出库,其它进仓,其它退货") + @JsonProperty("type") + private String type; + + @Schema(description = "分仓编号") + @JsonProperty("wms_co_id") + private Integer wmsCoId; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/OtherInoutQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/OtherInoutQuery.java new file mode 100644 index 00000000..3f8342c0 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/OtherInoutQuery.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.wms; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +public class OtherInoutQuery extends ModifiedTimeQuery { + + @Schema(description = "指定线上订单号,和时间段不能同时为空,,最多50个") + @JsonProperty("so_ids") + private List soIds; + + @Schema(description = "单据类型:其它退货,其它出库,其它进仓") + @JsonProperty("types") + private List types; + + @Schema(description = "单据状态,Confirmed生效,WaitConfirm待审核,OuterConfirming外部确认中,Cancelled取消(单据生效后的作废),Delete作废(单据生效前的作废)") + @JsonProperty("status") + private String status; + + @Schema(description = "分仓编号") + @JsonProperty("wms_co_id") + private Long wmsCoId; + + @Schema(description = "出仓单号列表,最多50个") + @JsonProperty("io_ids") + private List ioIds; + + @Schema(description = "0:修改时间,modified。 2:出入库时间 io_date,未传入时默认为0") + @JsonProperty("date_type") + private Integer dateType; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/TrackinfoQuery.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/TrackinfoQuery.java new file mode 100644 index 00000000..22b69240 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/request/wms/TrackinfoQuery.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.request.wms; + +import cn.sliew.carp.module.http.sync.remote.jst.request.ModifiedTimeQuery; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class TrackinfoQuery extends ModifiedTimeQuery { + + @Schema(description = "唯一码") + @JsonProperty("sku_sn") + private String skuSn; + + @Schema(description = "快递单号") + @JsonProperty("l_id") + private String lId; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/JstNewResult.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/JstNewResult.java new file mode 100644 index 00000000..3c021bed --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/JstNewResult.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class JstNewResult { + + private Integer code; + private String msg; + private T data; + @JsonProperty("request_id") + private String requestId; + + public boolean isSuccess() { + return code != null && code == 0; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/JstResult.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/JstResult.java new file mode 100644 index 00000000..6bd0b2cf --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/JstResult.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; +import org.springframework.lang.Nullable; + +import java.util.List; + +@Getter +@Setter +public class JstResult { + + @JsonProperty("page_index") + private int pageIndex; + + @JsonProperty("page_size") + private int pageSize; + + @Nullable + @JsonProperty("data_count") + private int dataCount; + + @Nullable + @JsonProperty("page_count") + private int pageCount; + + @JsonProperty("has_next") + private boolean hasNext; + + @JsonProperty("issuccess") + private boolean issuccess; + + private int code; + private String msg; + private List datas; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/auth/JstAccessTokenDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/auth/JstAccessTokenDO.java new file mode 100644 index 00000000..387613ae --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/auth/JstAccessTokenDO.java @@ -0,0 +1,50 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.auth; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class JstAccessTokenDO { + + /** + * 访问令牌 + */ + @JsonProperty("access_token") + private String accessToken; + + /** + * access_token访问过期时间【单位是秒】,还有多少秒后过期 + */ + @JsonProperty("expires_in") + private Long expiresIn; + + /** + * 更新令牌 + */ + @JsonProperty("refresh_token") + private String refreshToken; + + /** + * 固定值:all + */ + @JsonProperty("scope") + private String scope; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/JstShopsResult.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/JstShopsResult.java new file mode 100644 index 00000000..a3423e1a --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/JstShopsResult.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.base; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class JstShopsResult { + + private int code; + private boolean issuccess; + private String msg; + + private List shops; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/ShopDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/ShopDO.java new file mode 100644 index 00000000..59d98ffd --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/ShopDO.java @@ -0,0 +1,67 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.base; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class ShopDO { + + @JsonProperty("shop_id") + private Long shopId; + + @JsonProperty("shop_name") + private String shopName; + + @JsonProperty("co_id") + private Long coId; + + @JsonProperty("shop_site") + private String shopSite; + + @JsonProperty("shop_url") + private String shopUrl; + + @JsonProperty("created") + private String created; + + @JsonProperty("nick") + private String nick; + + @JsonProperty("session_expired") + private String sessionExpired; + + @JsonProperty("session_uid") + private String sessionUid; + + @JsonProperty("short_name") + private String shortName; + + @JsonProperty("organization") + private String organization; + + @JsonProperty("group_id") + private Long groupId; + + @JsonProperty("group_name") + private String groupName; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/WmsPartnerDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/WmsPartnerDO.java new file mode 100644 index 00000000..f5671fc0 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/base/WmsPartnerDO.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.base; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class WmsPartnerDO { + + /** + * 分仓名称 + */ + @JsonProperty("name") + private String name; + + /** + * 主仓公司编号 + */ + @JsonProperty("co_id") + private Integer coId; + + /** + * 分仓编号 + */ + @JsonProperty("wms_co_id") + private Integer wmsCoId; + + /** + * 是否为主仓,true=主仓 + */ + @JsonProperty("is_main") + private String isMain; + + /** + * 仓储列表里的状态,不是仓库账号的状态 + */ + @JsonProperty("status") + private String status; + + /** + * 我方备注 + */ + @JsonProperty("remark1") + private String remark1; + + /** + * 对方备注 + */ + @JsonProperty("remark2") + private String remark2; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/InventoryCountDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/InventoryCountDO.java new file mode 100644 index 00000000..03467790 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/InventoryCountDO.java @@ -0,0 +1,224 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.inventory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class InventoryCountDO { + + /** + * 单据类型 + */ + @JsonProperty("type") + private String type; + + /** + * 盘点单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 单据日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 状态;WaitConfirm:待确认,Confirmed:生效,Archive:归档,Cancelled:取消,Delete:作废 + */ + @JsonProperty("status") + private String status; + + /** + * 仓库名称 + */ + @JsonProperty("warehouse") + private String warehouse; + + /** + * 创建人 + */ + @JsonProperty("creator_name") + private String creatorName; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 仓库编号,主仓=1,销退仓=2, 进货仓=3,次品仓 = 4 + */ + @JsonProperty("wh_id") + private Long whId; + + /** + * 分仓编号 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 商品集合 + */ + private List items; + + /** + * 批次集合,获取该节点系统中相关业务项需配置 + */ + private List batchs; + + /** + * labels + */ + @JsonProperty("labels") + private List labels; + + /** + * ts + */ + @JsonProperty("ts") + private Long ts; + + /** + * f_status + */ + @JsonProperty("f_status") + private String fStatus; + + /** + * lock_wh_id + */ + @JsonProperty("lock_wh_id") + private Integer lockWhId; + + /** + * 唯一码集合,获取该节点系统中相关业务项需配置 + */ + @JsonProperty("sns") + private List sns; + + @Getter + @Setter + public static class ItemDO { + + /** + * 盘点单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 子单号 + */ + @JsonProperty("ioi_id") + private Long ioiId; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 颜色及规格 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 盘点后数量 + */ + @JsonProperty("r_qty") + private Integer rQty; + + /** + * 盈亏数量 + */ + @JsonProperty("qty") + private Integer qty; + } + + @Getter + @Setter + public static class BatchDO { + + /** + * 批次号 + */ + @JsonProperty("batch_no") + private String batchNo; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 批次日期 + */ + @JsonProperty("product_date") + private String productDate; + + /** + * 供应商编号 + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 供应商名称 + */ + @JsonProperty("supplier_name") + private String supplierName; + + /** + * 有效期至 + */ + @JsonProperty("expiration_date") + private String expirationDate; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/InventoryDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/InventoryDO.java new file mode 100644 index 00000000..c5faf68b --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/InventoryDO.java @@ -0,0 +1,142 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.inventory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class InventoryDO { + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 款式编码 + */ + @JsonProperty("i_id") + private String iId; + + /** + * 主仓实际库存 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 虚拟库存 + */ + @JsonProperty("order_lock") + private Integer orderLock; + + /** + * 店铺编号 + */ + @JsonProperty("virtual_qty") + private Integer virtualQty; + + /** + * 采购在途数 + */ + @JsonProperty("purchase_qty") + private Integer purchaseQty; + + /** + * 销退仓库存 + */ + @JsonProperty("return_qty") + private Integer returnQty; + + /** + * 进货仓库存 + */ + @JsonProperty("in_qty") + private Integer inQty; + + /** + * 次品库存 + */ + @JsonProperty("defective_qty") + private Integer defectiveQty; + + /** + * 修改时间,用此时间作为下一次查询的起始时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 安全库存下限 + */ + @JsonProperty("min_qty") + private Integer minQty; + + /** + * 安全库存上限 + */ + @JsonProperty("max_qty") + private Integer maxQty; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 仓库待发数 + */ + @JsonProperty("pick_lock") + private Integer pickLock; + + /** + * 调拨在途数 + */ + @JsonProperty("allocate_qty") + private Integer allocateQty; + + /** + * 时间戳 + */ + @JsonProperty("ts") + private Long ts; + + /** + * 自定义仓1 + */ + @JsonProperty("customize_qty_1") + private Integer customizeQty1; + + /** + * 自定义仓2 + */ + @JsonProperty("customize_qty_2") + private Integer customizeQty2; + + /** + * 自定义仓3 + */ + @JsonProperty("customize_qty_3") + private Integer customizeQty3; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/JstInventoryResult.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/JstInventoryResult.java new file mode 100644 index 00000000..1a7f6978 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/JstInventoryResult.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.inventory; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.inventory.InventoryDO; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class JstInventoryResult extends JstResult { + + @JsonIgnoreProperties(allowGetters = false, allowSetters = true) + private List inventorys; + + @Override + public List getDatas() { + return inventorys; + } + + @Override + public void setDatas(List datas) { + this.inventorys = inventorys; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/PackDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/PackDO.java new file mode 100644 index 00000000..43c09dfe --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/inventory/PackDO.java @@ -0,0 +1,106 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.inventory; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class PackDO { + + /** + * 仓库id + */ + @JsonProperty("wms_co_id") + private Integer wmsCoId; + + /** + * 箱号 + */ + @JsonProperty("pack_id") + private String packId; + + /** + * 仓库编号;1=主仓,2=销退仓, 3=进货仓,4=次品仓 + */ + @JsonProperty("wh_id") + private Integer whId; + + /** + * 类型 + */ + @JsonProperty("pack_type") + private String packType; + + /** + * 仓位 + */ + @JsonProperty("bin") + private String bin; + + /** + * 明细仓位 + */ + @JsonProperty("item_bin") + private String itemBin; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 有效期 + */ + @JsonProperty("expiration_date") + private String expirationDate; + + /** + * 生产日期 + */ + @JsonProperty("product_date") + private String productDate; + + /** + * 生产批次 + */ + @JsonProperty("batch_no") + private String batchNo; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 供应商ID + */ + @JsonProperty("supplier_id") + private String supplierId; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/CategoryDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/CategoryDO.java new file mode 100644 index 00000000..6b7dcc8d --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/CategoryDO.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.item; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CategoryDO { + + /** + * 类目id + */ + @JsonProperty("c_id") + private Long cId; + + /** + * 父级类目id + */ + @JsonProperty("parent_c_id") + private Long parentCId; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 类目名称 + */ + @JsonProperty("name") + private String name; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/CombineSkuDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/CombineSkuDO.java new file mode 100644 index 00000000..8291805e --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/CombineSkuDO.java @@ -0,0 +1,270 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.item; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class CombineSkuDO { + + /** + * 组合款式编码 + */ + @JsonProperty("i_id") + private String iId; + + /** + * 组合商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 简称 + */ + @JsonProperty("short_name") + private String shortName; + + /** + * 虚拟分类 + */ + @JsonProperty("vc_name") + private String vcName; + + /** + * 图片地址 + */ + @JsonProperty("pic") + private String pic; + + /** + * 组合颜色及规格 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 组合售价 + */ + @JsonProperty("sale_price") + private BigDecimal salePrice; + + /** + * 组合重量 + */ + @JsonProperty("weight") + private BigDecimal weight; + + /** + * 组合装编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 组合装商品成本价 + */ + @JsonProperty("cost_price") + private Integer costPrice; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 商品列表 + */ + private List items; + + /** + * 组合商品实体编码 + */ + @JsonProperty("enty_sku_id") + private String entySkuId; + + /** + * 标签 + */ + @JsonProperty("labels") + private String labels; + + /** + * 品牌 + */ + @JsonProperty("brand") + private String brand; + + /** + * 是否启用1表示启用;0表示备用;-1表示禁用 + */ + @JsonProperty("enabled") + private Integer enabled; + + /** + * sku_qty + */ + @JsonProperty("sku_qty") + private Integer skuQty; + + /** + * 国际码 + */ + @JsonProperty("sku_code") + private String skuCode; + + /** + * 其他价格1 + */ + @JsonProperty("other_price_1") + private BigDecimal otherPrice1; + + /** + * 其他价格2 + */ + @JsonProperty("other_price_2") + private BigDecimal otherPrice2; + + /** + * 其他价格3 + */ + @JsonProperty("other_price_3") + private BigDecimal otherPrice3; + + /** + * 其他价格4 + */ + @JsonProperty("other_price_4") + private BigDecimal otherPrice4; + + /** + * 其他价格5 + */ + @JsonProperty("other_price_5") + private BigDecimal otherPrice5; + + /** + * 其他属性1 + */ + @JsonProperty("other_1") + private String other1; + + /** + * 其他属性2 + */ + @JsonProperty("other_2") + private String other2; + + /** + * 其他属性3 + */ + @JsonProperty("other_3") + private String other3; + + /** + * 其他属性4 + */ + @JsonProperty("other_4") + private String other4; + + /** + * 其他属性5 + */ + @JsonProperty("other_5") + private String other5; + + /** + * 长 + */ + @JsonProperty("l") + private BigDecimal l; + + /** + * 宽 + */ + @JsonProperty("w") + private BigDecimal w; + + /** + * 高 + */ + @JsonProperty("h") + private BigDecimal h; + + /** + * 体积 + */ + @JsonProperty("volume") + private BigDecimal volume; + + /** + * 商品属性,成品,半成品,原材料,包材 + */ + @JsonProperty("item_type") + private String itemType; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + @Getter + @Setter + public static class ItemDO { + + /** + * 子商品编码 + */ + @JsonProperty("src_sku_id") + private String srcSkuId; + + /** + * 子商品数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 售价 + */ + @JsonProperty("sale_price") + private BigDecimal salePrice; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/MallItemDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/MallItemDO.java new file mode 100644 index 00000000..d4dce465 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/MallItemDO.java @@ -0,0 +1,478 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.item; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class MallItemDO { + + /** + * 款式编码 + */ + @JsonProperty("i_id") + private String iId; + + /** + * 公司编号 + */ + @JsonProperty("co_id") + private Long coId; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 商品分类编号 + */ + @JsonProperty("c_id") + private Long cId; + + /** + * 商品分类名称 + */ + @JsonProperty("c_name") + private String cName; + + /** + * 基本售价(款式) + */ + @JsonProperty("s_price") + private BigDecimal sPrice; + + /** + * 成本价(采购价) + */ + @JsonProperty("c_price") + private BigDecimal cPrice; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 图片地址 + */ + @JsonProperty("pic") + private String pic; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 品牌 + */ + @JsonProperty("brand") + private String brand; + + /** + * 重量 + */ + @JsonProperty("weight") + private BigDecimal weight; + + /** + * 市场|吊牌价 + */ + @JsonProperty("market_price") + private BigDecimal marketPrice; + + /** + * 虚拟分类 + */ + @JsonProperty("vc_name") + private String vcName; + + /** + * 商品属性:成品/半成品/原材料 + */ + @JsonProperty("item_type") + private String itemType; + + /** + * 长 + */ + @JsonProperty("l") + private BigDecimal l; + + /** + * 宽 + */ + @JsonProperty("w") + private BigDecimal w; + + /** + * 高 + */ + @JsonProperty("h") + private BigDecimal h; + + /** + * 保质期(天) + */ + @JsonProperty("shelf_life") + private Integer shelfLife; + + /** + * sku列表 + */ + private List skus; + + /** + * 商品属性集合 + */ + private List ups; + + /** + * 生产批次信息 + */ + @JsonProperty("productionbatch_format") + private String productionbatchFormat; + + /** + * 生产许可证 + */ + @JsonProperty("production_licence") + private String productionLicence; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + @Getter + @Setter + public static class SkuDO { + + /** + * 公司编号 + */ + @JsonProperty("co_id") + private Long coId; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 款式编码 + */ + @JsonProperty("i_id") + private String iId; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 商品分类编号 + */ + @JsonProperty("c_id") + private Integer cId; + + /** + * 品牌 + */ + @JsonProperty("brand") + private String brand; + + /** + * 市场|吊牌价 + */ + @JsonProperty("market_price") + private BigDecimal marketPrice; + + /** + * 基本售价 + */ + @JsonProperty("sale_price") + private BigDecimal salePrice; + + /** + * 成本价 + */ + @JsonProperty("cost_price") + private BigDecimal costPrice; + + /** + * 是否启用,默认值1, 可选值: -1=禁用, 0=备用, 1=启用 + */ + @JsonProperty("enabled") + private Integer enabled; + + /** + * 分类 + */ + @JsonProperty("category") + private String category; + + /** + * 创建人编号 + */ + @JsonProperty("creator") + private String creator; + + /** + * 修改人编号 + */ + @JsonProperty("modifier") + private String modifier; + + /** + * 创建人名称 + */ + @JsonProperty("creator_name") + private String creatorName; + + /** + * 修改人名称 + */ + @JsonProperty("modifier_name") + private String modifierName; + + /** + * 颜色规格 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 国际码 + */ + @JsonProperty("sku_code") + private String skuCode; + + /** + * 图片地址 + */ + @JsonProperty("pic") + private String pic; + + /** + * 大图地址 + */ + @JsonProperty("pic_big") + private String picBig; + + /** + * 重量 + */ + @JsonProperty("weight") + private BigDecimal weight; + + /** + * 简称 + */ + @JsonProperty("short_name") + private String shortName; + + /** + * 商品属性,可选值["成品", "半成品", "原材料", "包材"] + */ + @JsonProperty("item_type") + private String itemType; + + /** + * 供应商编号 + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 供应商名称 + */ + @JsonProperty("supplier_name") + private String supplierName; + + /** + * 供应商商品编码 + */ + @JsonProperty("supplier_sku_id") + private String supplierSkuId; + + /** + * 供应商款式编码 + */ + @JsonProperty("supplier_i_id") + private String supplierIId; + + /** + * 商品备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 虚拟分类 + */ + @JsonProperty("vc_name") + private String vcName; + + /** + * 长 + */ + @JsonProperty("l") + private BigDecimal l; + + /** + * 宽 + */ + @JsonProperty("w") + private BigDecimal w; + + /** + * 高 + */ + @JsonProperty("h") + private BigDecimal h; + + /** + * 其他价格1 + */ + @JsonProperty("other_price_1") + private BigDecimal otherPrice1; + + /** + * 其他价格2 + */ + @JsonProperty("other_price_2") + private BigDecimal otherPrice2; + + /** + * 其他价格3 + */ + @JsonProperty("other_price_3") + private BigDecimal otherPrice3; + + /** + * 其他价格4 + */ + @JsonProperty("other_price_4") + private BigDecimal otherPrice4; + + /** + * 其他价格5 + */ + @JsonProperty("other_price_5") + private BigDecimal otherPrice5; + + /** + * 商品标签,多个标签时以逗号分隔 + */ + @JsonProperty("labels") + private String labels; + + /** + * 其他属性1 + */ + @JsonProperty("other_1") + private String other1; + + /** + * 其他属性2 + */ + @JsonProperty("other_2") + private String other2; + + /** + * 其他属性3 + */ + @JsonProperty("other_3") + private String other3; + + /** + * 其他属性4 + */ + @JsonProperty("other_4") + private String other4; + + /** + * 其他属性5 + */ + @JsonProperty("other_5") + private String other5; + + /** + * 保质期 + */ + @JsonProperty("shelf_life") + private Integer shelfLife; + + /** + * 生产批次信息 + */ + @JsonProperty("productionbatch_format") + private String productionbatchFormat; + + /** + * 生产许可证 + */ + @JsonProperty("production_licence") + private String productionLicence; + } + + @Getter + @Setter + public static class UpDO { + + /** + * 属性编号 + */ + @JsonProperty("p_id") + private Long pId; + + /** + * 属性列名 + */ + @JsonProperty("p_name") + private String pName; + + /** + * 属性值编号 + */ + @JsonProperty("pv_id") + private Long pvId; + + /** + * 属性值名称 + */ + @JsonProperty("pv_value") + private String pvValue; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/SkuDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/SkuDO.java new file mode 100644 index 00000000..c9452915 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/SkuDO.java @@ -0,0 +1,336 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.item; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; + +@Getter +@Setter +public class SkuDO { + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 款式编码 + */ + @JsonProperty("i_id") + private String iId; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 商品简称 + */ + @JsonProperty("short_name") + private String shortName; + + /** + * 销售价 + */ + @JsonProperty("sale_price") + private BigDecimal salePrice; + + /** + * 成本价 + */ + @JsonProperty("cost_price") + private BigDecimal costPrice; + + /** + * 颜色规格 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 类目id + */ + @JsonProperty("c_id") + private Integer cId; + + /** + * 分类 + */ + @JsonProperty("category") + private String category; + + /** + * 大图地址 + */ + @JsonProperty("pic_big") + private String picBig; + + /** + * 图片地址 + */ + @JsonProperty("pic") + private String pic; + + /** + * 是否启用,0:备用,1:启用,-1:禁用 + */ + @JsonProperty("enabled") + private Integer enabled; + + /** + * 重量 + */ + @JsonProperty("weight") + private BigDecimal weight; + + /** + * 市场价 + */ + @JsonProperty("market_price") + private BigDecimal marketPrice; + + /** + * 品牌 + */ + @JsonProperty("brand") + private String brand; + + /** + * 供应商编号 + */ + @JsonProperty("supplier_id") + private String supplierId; + + /** + * 供应商名称 + */ + @JsonProperty("supplier_name") + private String supplierName; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 国际码 + */ + @JsonProperty("sku_code") + private String skuCode; + + /** + * 颜色 + */ + @JsonProperty("color") + private String color; + + /** + * 供应商商品编码 + */ + @JsonProperty("supplier_sku_id") + private String supplierSkuId; + + /** + * 供应商商品款号 + */ + @JsonProperty("supplier_i_id") + private String supplierIId; + + /** + * 虚拟分类 + */ + @JsonProperty("vc_name") + private String vcName; + + /** + * 商品类型 + */ + @JsonProperty("sku_type") + private String skuType; + + /** + * 创建者 + */ + @JsonProperty("creator") + private String creator; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 未知 + */ + @JsonProperty("autoid") + private Long autoid; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 商品属性,成品,半成品,原材料,包材 + */ + @JsonProperty("item_type") + private String itemType; + + /** + * 是否禁止同步,0=启用同步,1=禁用同步,2=部分禁用 + */ + @JsonProperty("stock_disabled") + private String stockDisabled; + + /** + * 单位 + */ + @JsonProperty("unit") + private String unit; + + /** + * 保质期 + */ + @JsonProperty("shelf_life") + private Integer shelfLife; + + /** + * 商品标签,多个标签时以逗号分隔 + */ + @JsonProperty("labels") + private String labels; + + /** + * 生产批次信息 + */ + @JsonProperty("productionbatch_format") + private String productionbatchFormat; + + /** + * 生产许可证 + */ + @JsonProperty("production_licence") + private String productionLicence; + + /** + * 长 + */ + @JsonProperty("l") + private BigDecimal l; + + /** + * 宽 + */ + @JsonProperty("w") + private BigDecimal w; + + /** + * 高 + */ + @JsonProperty("h") + private BigDecimal h; + + /** + * 是否开启序列号 + */ + @JsonProperty("is_series_number") + private Boolean isSeriesNumber; + + /** + * 其他价格1 + */ + @JsonProperty("other_price_1") + private BigDecimal otherPrice1; + + /** + * 其他价格2 + */ + @JsonProperty("other_price_2") + private BigDecimal otherPrice2; + + /** + * 其他价格3 + */ + @JsonProperty("other_price_3") + private BigDecimal otherPrice3; + + /** + * 其他价格4 + */ + @JsonProperty("other_price_4") + private BigDecimal otherPrice4; + + /** + * 其他价格5 + */ + @JsonProperty("other_price_5") + private BigDecimal otherPrice5; + + /** + * 其他属性1 + */ + @JsonProperty("other_1") + private String other1; + + /** + * 其他属性2 + */ + @JsonProperty("other_2") + private String other2; + + /** + * 其他属性3 + */ + @JsonProperty("other_3") + private String other3; + + /** + * 其他属性4 + */ + @JsonProperty("other_4") + private String other4; + + /** + * 其他属性5 + */ + @JsonProperty("other_5") + private String other5; + + /** + * 链接同步状态 + */ + @JsonProperty("stock_type") + private String stockType; + + /** + * 是否启用生产批次 + */ + @JsonProperty("batch_enabled") + private Boolean batchEnabled; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/SkumapDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/SkumapDO.java new file mode 100644 index 00000000..203e4164 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/item/SkumapDO.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.item; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class SkumapDO { + + /** + * 店铺 id + */ + @JsonProperty("shop_id") + private Long shopId; + + /** + * 平台 + */ + @JsonProperty("channel") + private String channel; + + /** + * 款号 id + */ + @JsonProperty("i_id") + private String iId; + + /** + * 商品 id + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 店铺款号 id + */ + @JsonProperty("shop_i_id") + private String shopIId; + + /** + * 店铺商品 id + */ + @JsonProperty("shop_sku_id") + private String shopSkuId; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 商品对应关系修改时间 + */ + @JsonProperty("link_modified") + private String linkModified; + + /** + * 是否在售 + */ + @JsonProperty("enabled") + private String enabled; + + /** + * 公司编号 + */ + @JsonProperty("co_id") + private Long coId; + + /** + * 类目编码 + */ + @JsonProperty("c_id") + private Integer cId; + + /** + * 原始商品编码 + */ + @JsonProperty("raw_sku_id") + private String rawSkuId; + + /** + * 平台价格,系统中需开启相关配置 + */ + @JsonProperty("shop_price") + private String shopPrice; + + /** + * 平台商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 图片地址 + */ + @JsonProperty("pic") + private String pic; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 下架时间 + */ + @JsonProperty("pull_off_time") + private String pullOffTime; + + /** + * 线上国标码 + */ + @JsonProperty("outer_sku_code") + private String outerSkuCode; + + /** + * 线上颜色规格 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 链接同步设置,0是开启同步,2是禁止同步 + */ + @JsonProperty("type") + private Integer type; + + /** + * 店铺库存 + */ + @JsonProperty("shop_qty") + private Integer shopQty; + + /** + * 对应商品编码(商品对应关系页面) + */ + @JsonProperty("link_sku_id") + private String linkSkuId; + + /** + * 售价下限 + */ + @JsonProperty("sale_price_min") + private Integer salePriceMin; + + /** + * 售价上限 + */ + @JsonProperty("sale_price_max") + private Integer salePriceMax; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/JstLogisticResult.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/JstLogisticResult.java new file mode 100644 index 00000000..e5e8cb34 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/JstLogisticResult.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.logistics; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.logistics.LogisticDO; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class JstLogisticResult extends JstResult { + + @JsonIgnoreProperties(allowGetters = false, allowSetters = true) + private List orders; + + @Override + public void setDatas(List datas) { + this.orders = datas; + } + + @Override + public List getDatas() { + return orders; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/LogisticDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/LogisticDO.java new file mode 100644 index 00000000..741011a7 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/LogisticDO.java @@ -0,0 +1,130 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.logistics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class LogisticDO { + + /** + * ERP订单号;唯一 + */ + @JsonProperty("o_id") + private Long oId; + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Long shopId; + + /** + * 订单号,最长不超过 50;唯一 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 发货时间 + */ + @JsonProperty("send_date") + private String sendDate; + + /** + * 运费 + */ + @JsonProperty("freight") + private BigDecimal freight; + + /** + * 重量 + */ + @JsonProperty("weight") + private Long weight; + + /** + * 快递公司代码 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 快递单号 + */ + @JsonProperty("l_id") + private String lId; + + /** + * 快递公司 + */ + @JsonProperty("logistics_company") + private String logisticsCompany; + + /** + * 订单明细;商品信息 + */ + private List items; + + // @Getter +// @Setter + @Data + public static class ItemDO { + + /** + * 商家SKU,对应库存管理的 SKU + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 购买数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 子订单号 + */ + @JsonProperty("outer_oi_id") + private String outerOiId; + + /** + * 原始平台订单号,可以为空,最长不超过 50 + */ + @JsonProperty("raw_so_id") + private String rawSoId; + + /** + * 内部单号 + */ + @JsonProperty("o_id") + private String oId; + + /** + * 商品退款状态 + */ + @JsonProperty("refund_status") + private String refundStatus; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/LogisticscompanyDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/LogisticscompanyDO.java new file mode 100644 index 00000000..5382dc99 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/logistics/LogisticscompanyDO.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.logistics; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class LogisticscompanyDO { + + /** + * 快递公司编码,ERP唯一 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 快递公司 + */ + @JsonProperty("lc_name") + private String lcName; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/AftersaleReceivedDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/AftersaleReceivedDO.java new file mode 100644 index 00000000..87e47227 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/AftersaleReceivedDO.java @@ -0,0 +1,207 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.order; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; + +@Getter +@Setter +public class AftersaleReceivedDO { + + /** + * 内部单号 + */ + @JsonProperty("o_id") + private Long oId; + + /** + * 出库单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 售后订单号 + */ + @JsonProperty("as_id") + private Long asId; + + /** + * 线上单号 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 出库日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 仓库名称 + */ + @JsonProperty("warehouse") + private String warehouse; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 物流公司编码 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Long shopId; + + /** + * 仓库代码(1 主仓,2 销退仓,3 进货仓,4 次品仓) + */ + @JsonProperty("wh_id") + private Long whId; + + /** + * 分仓编号 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 分销商名称 + */ + @JsonProperty("drp_co_name") + private String drpCoName; + + /** + * 商品集合 + */ + private List items; + + /** + * 批次信息集合 + */ + private List batchs; + + /** + * 分销商编号 + */ + @JsonProperty("drp_co_id") + private Integer drpCoId; + + @Getter + @Setter + public static class ItemDO { + + /** + * 出库单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 商品数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 属性值 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 销售价格 + */ + @JsonProperty("sale_price") + private BigDecimal salePrice; + + /** + * 销售数量 + */ + @JsonProperty("sale_amount") + private BigDecimal saleAmount; + } + + @Getter + @Setter + public static class BatchDO { + + /** + * 批次号 + */ + @JsonProperty("batch_no") + private String batchNo; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 商品数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 批次日期 + */ + @JsonProperty("product_date") + private String productDate; + + /** + * 供应商编号 + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 供应商名称 + */ + @JsonProperty("supplier_name") + private String supplierName; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/JstOrdersResult.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/JstOrdersResult.java new file mode 100644 index 00000000..fe483e95 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/JstOrdersResult.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.order; + +import cn.sliew.carp.module.http.sync.remote.jst.response.JstResult; +import cn.sliew.carp.module.http.sync.remote.jst.response.order.OrdersSingleDO; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class JstOrdersResult extends JstResult { + + @JsonIgnoreProperties(allowGetters = false, allowSetters = true) + private List orders; + + @Override + public void setDatas(List datas) { + this.orders = datas; + } + + @Override + public List getDatas() { + return orders; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrderActionDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrderActionDO.java new file mode 100644 index 00000000..8c4a948b --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrderActionDO.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.order; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class OrderActionDO { + + /** + * 日志id + */ + @JsonProperty("oa_id") + private Long oaId; + + /** + * 订单id + */ + @JsonProperty("o_id") + private Long oId; + + /** + * 操作名称 + */ + @JsonProperty("name") + private String name; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 操作时间 + */ + @JsonProperty("created") + private String created; + + /** + * 创建人 + */ + @JsonProperty("creator_name") + private String creatorName; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrdersOutSimpleDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrdersOutSimpleDO.java new file mode 100644 index 00000000..99b3c602 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrdersOutSimpleDO.java @@ -0,0 +1,351 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.order; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class OrdersOutSimpleDO { + + @JsonProperty("co_id") + @Schema(description = "公司编号") + private Long coId; + + @JsonProperty("shop_id") + @Schema(description = "店铺编号") + private Long shopId; + + @JsonProperty("io_id") + @Schema(description = "出库单号") + private Long ioId; + + @JsonProperty("o_id") + @Schema(description = "内部单号") + private Long oId; + + @JsonProperty("so_id") + @Schema(description = "线上单号") + private String soId; + + @JsonProperty("created") + @Schema(description = "创建时间") + private String created; + + @JsonProperty("modified") + @Schema(description = "修改时间") + private String modified; + + @JsonProperty("status") + @Schema(description = "状态;Archive:归档,WaitConfirm:待出库,Confirmed:已出库," + + "Cancelled:取消,Delete:作废,OuterConfirming:外部发货中") + private String status; + + @JsonProperty("order_type") + @Schema(description = "单据类型") + private String orderType; + + @JsonProperty("invoice_title") + @Schema(description = "发票抬头") + private String invoiceTitle; + + @JsonProperty("shop_buyer_id") + @Schema(description = "买家帐号") + private String shopBuyerId; + + @JsonProperty("receiver_country") + @Schema(description = "国家") + private String receiverCountry; + + @JsonProperty("receiver_state") + @Schema(description = "省") + private String receiverState; + + @JsonProperty("receiver_city") + @Schema(description = "市") + private String receiverCity; + + @JsonProperty("receiver_district") + @Schema(description = "区") + private String receiverDistrict; + + @JsonProperty("receiver_town") + @Schema(description = "街道") + private String receiverTown; + + @JsonProperty("receiver_address") + @Schema(description = "地址") + private String receiverAddress; + + @JsonProperty("receiver_name") + @Schema(description = "收件人姓名") + private String receiverName; + + @JsonProperty("receiver_phone") + @Schema(description = "收件人手机") + private String receiverPhone; + + @JsonProperty("receiver_mobile") + @Schema(description = "收件人电话") + private String receiverMobile; + + @JsonProperty("buyer_message") + @Schema(description = "买家留言") + private String buyerMessage; + + @JsonProperty("remark") + @Schema(description = "备注") + private String remark; + + @JsonProperty("is_cod") + @Schema(description = "是否货到付款") + private String isCod; + + @JsonProperty("pay_amount") + @Schema(description = "应付金额") + private BigDecimal payAmount; + + @JsonProperty("l_id") + @Schema(description = "物流单号") + private String lId; + + @JsonProperty("io_date") + @Schema(description = "出库时间") + private String ioDate; + + @JsonProperty("lc_id") + @Schema(description = "快递公司编码") + private String lcId; + + @JsonProperty("stock_enabled") + @Schema(description = "是否启用库存管理") + private String stockEnabled; + + @JsonProperty("drp_co_id_from") + @Schema(description = "分销商编号") + private String drpCoIdFrom; + + @JsonProperty("labels") + @Schema(description = "标记|多标签") + private String labels; + + @JsonProperty("paid_amount") + @Schema(description = "实付金额") + private BigDecimal paidAmount; + + @JsonProperty("free_amount") + @Schema(description = "优惠金额") + private BigDecimal freeAmount; + + @JsonProperty("freight") + @Schema(description = "运费") + private BigDecimal freight; + + @JsonProperty("weight") + @Schema(description = "预估重量") + private BigDecimal weight; + + @JsonProperty("f_weight") + @Schema(description = "实称重量") + private BigDecimal fWeight; + + @JsonProperty("merge_so_id") + @Schema(description = "合并订单号") + private String mergeSoId; + + @JsonProperty("wms_co_id") + @Schema(description = "分仓编号") + private Long wmsCoId; + + @JsonProperty("business_staff") + @Schema(description = "业务人员") + private String businessStaff; + + @JsonProperty("currency") + @Schema(description = "货币类型") + private String currency; + + @Schema(description = "商品集合") + private List items; + + @Schema(description = "批次集合,获取该节点系统中相关业务项需配置") + private List batchs; + + @Schema(description = "唯一码集合,获取该节点系统中相关业务项需配置") + private List sns; + + @JsonProperty("pay_date") + @Schema(description = "付款日期") + private String payDate; + + @JsonProperty("logistics_company") + @Schema(description = "物流公司名称") + private String logisticsCompany; + + @JsonProperty("shop_name") + private String shopName; + + @JsonProperty("buyer_id") + private String buyerId; + + @JsonProperty("qty") + private Integer qty; + + @JsonProperty("f_freight") + private String fFreight; + + @JsonProperty("node") + private String node; + + @JsonProperty("seller_flag") + private Integer sellerFlag; + + @JsonProperty("open_id") + private String openId; + + @JsonProperty("wave_id") + private Long waveId; + + @JsonProperty("order_staff_id") + private Long orderStaffId; + + @JsonProperty("order_staff_name") + private String orderStaffName; + + @JsonProperty("is_print_express") + private String isPrintExpress; + + @JsonProperty("is_print") + private String isPrint; + + @JsonProperty("ts") + private Long ts; + + @JsonProperty("ClusterInfos") + private List clusterInfos; + + @Getter + @Setter + public static class ItemDO { + + @JsonProperty("ioi_id") + @Schema(description = "子单号") + private Long ioiId; + + @JsonProperty("pic") + @Schema(description = "图片") + private String pic; + + @JsonProperty("sku_id") + @Schema(description = "商品编码") + private String skuId; + + @JsonProperty("qty") + @Schema(description = "数量") + private Integer qty; + + @JsonProperty("name") + @Schema(description = "商品名称") + private String name; + + @JsonProperty("properties_value") + @Schema(description = "颜色规格") + private String propertiesValue; + + @JsonProperty("sale_price") + @Schema(description = "单价") + private BigDecimal salePrice; + + @JsonProperty("sale_amount") + @Schema(description = "金额") + private BigDecimal saleAmount; + + @JsonProperty("i_id") + @Schema(description = "款式编码") + private String iId; + + @JsonProperty("sale_base_price") + @Schema(description = "原价") + private BigDecimal saleBasePrice; + + @JsonProperty("combine_sku_id") + @Schema(description = "组合装商品编码") + private String combineSkuId; + + @JsonProperty("is_gift") + @Schema(description = "是否赠品") + private Boolean isGift; + + @JsonProperty("raw_so_id") + private String rawSoId; + } + + @Getter + @Setter + public static class BatchDO { + + @JsonProperty("batch_no") + @Schema(description = "批次号") + private String batchNo; + + @JsonProperty("sku_id") + @Schema(description = "商品编码") + private String skuId; + + @JsonProperty("qty") + @Schema(description = "数量") + private Integer qty; + + @JsonProperty("product_date") + @Schema(description = "批次日期") + private String productDate; + + @JsonProperty("supplier_id") + @Schema(description = "供应商编号") + private Long supplierId; + + @JsonProperty("supplier_name") + @Schema(description = "供应商名称") + private String supplierName; + + @JsonProperty("expiration_date") + @Schema(description = "有效期至") + private String expirationDate; + } + + @Getter + @Setter + public static class SnDO { + + @JsonProperty("sku_id") + @Schema(description = "商品编码") + private String skuId; + + @JsonProperty("sn") + @Schema(description = "唯一码") + private String sn; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrdersSingleDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrdersSingleDO.java new file mode 100644 index 00000000..554b0219 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/order/OrdersSingleDO.java @@ -0,0 +1,736 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.order; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class OrdersSingleDO { + + /** + * 是否货到付款 + */ + @JsonProperty("is_cod") + private String isCod; + + /** + * 快递单号 + */ + @JsonProperty("l_id") + private String lId; + + /** + * 发货日期 + */ + @JsonProperty("send_date") + private String sendDate; + + /** + * 支付时间 + */ + @JsonProperty("pay_date") + private String payDate; + + /** + * 运费,保留两位小数,单位(元) + */ + @JsonProperty("freight") + private String freight; + + /** + * 收货地址 + */ + @JsonProperty("receiver_address") + private String receiverAddress; + + /** + * 区 + */ + @JsonProperty("receiver_district") + private String receiverDistrict; + + /** + * 发货仓编号 + */ + @JsonProperty("wms_co_id") + private String wmsCoId; + + /** + * 快递公司 + */ + @JsonProperty("logistics_company") + private String logisticsCompany; + + /** + * 抵扣金额 + */ + @JsonProperty("free_amount") + private String freeAmount; + + /** + * 店铺名称 + */ + @JsonProperty("shop_name") + private String shopName; + + /** + * 问题类型,仅当问题订单时有效 + */ + @JsonProperty("question_type") + private String questionType; + + /** + * 外部支付单号 + */ + @JsonProperty("outer_pay_id") + private String outerPayId; + + /** + * 线上订单号,最长不超过 20;唯一 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 订单类型 + */ + @JsonProperty("type") + private String type; + + /** + * 订单来源 + */ + @JsonProperty("order_from") + private String orderFrom; + + /** + * 待付款:WaitPay;发货中:Delivering;被合并:Merged;异常:Question;被拆分:Split;等供销商|外仓发货:WaitOuterSent;已付款待审核:WaitConfirm;已客审待财审:WaitFConfirm;已发货:Sent;取消:Cancelled + */ + @JsonProperty("status") + private String status; + + /** + * 应付金额,保留两位小数,单位(元) + */ + @JsonProperty("pay_amount") + private String payAmount; + + /** + * 买家昵称 + */ + @JsonProperty("shop_buyer_id") + private String shopBuyerId; + + /** + * 平台订单状态 + */ + @JsonProperty("shop_status") + private String shopStatus; + + /** + * 手机 + */ + @JsonProperty("receiver_mobile") + private String receiverMobile; + + /** + * 下单时间 + */ + @JsonProperty("order_date") + private String orderDate; + + /** + * 问题描述 + */ + @JsonProperty("question_desc") + private String questionDesc; + + /** + * 收件信息-市 + */ + @JsonProperty("receiver_city") + private String receiverCity; + + /** + * 收件信息-省 + */ + @JsonProperty("receiver_state") + private String receiverState; + + /** + * 收件信息-收件人 + */ + @JsonProperty("receiver_name") + private String receiverName; + + /** + * ERP 内部订单号,唯一 + */ + @JsonProperty("o_id") + private Long oId; + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Long shopId; + + /** + * 公司编号 + */ + @JsonProperty("co_id") + private Long coId; + + /** + * 支付信息 + */ + private List pays; + + /** + * 商品信息 + */ + private List items; + + /** + * 订单备注;卖家备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 分销商编号 + */ + @JsonProperty("drp_co_id_from") + private String drpCoIdFrom; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 多标签 + */ + @JsonProperty("labels") + private String labels; + + /** + * 实际支付金额 + */ + @JsonProperty("paid_amount") + private String paidAmount; + + /** + * 币种 + */ + @JsonProperty("currency") + private String currency; + + /** + * 买家留言 + */ + @JsonProperty("buyer_message") + private String buyerMessage; + + /** + * 物流公司编码 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 发票抬头 + */ + @JsonProperty("invoice_title") + private String invoiceTitle; + + /** + * 发票类型 + */ + @JsonProperty("invoice_type") + private String invoiceType; + + /** + * 发票税号 + */ + @JsonProperty("buyer_tax_no") + private String buyerTaxNo; + + /** + * 业务员 + */ + @JsonProperty("creator_name") + private String creatorName; + + /** + * 计划发货时间 + */ + @JsonProperty("plan_delivery_date") + private String planDeliveryDate; + + /** + * 线下备注 + */ + @JsonProperty("node") + private String node; + + /** + * 收件信息-街道 + */ + @JsonProperty("receiver_town") + private String receiverTown; + + /** + * 供销商编号 + */ + @JsonProperty("drp_co_id_to") + private String drpCoIdTo; + + /** + * 运费成本 + */ + @JsonProperty("f_freight") + private String fFreight; + + /** + * 店铺站点信息 + */ + @JsonProperty("shop_site") + private String shopSite; + + /** + * 国际物流单号 + */ + @JsonProperty("un_lid") + private String unLid; + + /** + * 收货时间(仅限头条放心购、京东、拼多多) + */ + @JsonProperty("end_time") + private String endTime; + + /** + * 国家代码; + */ + @JsonProperty("receiver_country") + private String receiverCountry; + + /** + * 邮编 + */ + @JsonProperty("receiver_zip") + private String receiverZip; + + /** + * 旗帜(1红旗,2黄旗,3绿旗,4蓝旗,5紫旗)) + */ + @JsonProperty("seller_flag") + private Integer sellerFlag; + + /** + * 平台买家唯一值,仅支持抖音,快手,小红书 + */ + @JsonProperty("open_id") + private String openId; + + /** + * 电话 + */ + @JsonProperty("receiver_phone") + private String receiverPhone; + + /** + * 补发换货单对应的售后单号 + */ + @JsonProperty("as_id") + private String asId; + + /** + * 收货邮箱 + */ + @JsonProperty("receiver_email") + private String receiverEmail; + + /** + * '主播id' + */ + @JsonProperty("referrer_id") + private String referrerId; + + /** + * 主播名称 + */ + @JsonProperty("referrer_name") + private String referrerName; + + /** + * 订单创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 商品(商品总数.sku_id*qty + */ + @JsonProperty("skus") + private String skus; + + /** + * 实称重量 + */ + @JsonProperty("f_weight") + private String fWeight; + + /** + * 重量 + */ + @JsonProperty("weight") + private String weight; + + /** + * 数据库行版本号:https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/rowversion-transact-sql?view=sql-server-ver16 + */ + @JsonProperty("ts") + private Long ts; + + /** + * 买家ID(系统根据shop_buy_id生成的) + */ + @JsonProperty("buyer_id") + private String buyerId; + + /** + * 买家实付(仅限抖音,拼多多,京东平台订单) + */ + @JsonProperty("buyer_paid_amount") + private String buyerPaidAmount; + + /** + * 卖家实收(仅限抖音,拼多多,京东平台订单) + */ + @JsonProperty("seller_income_amount") + private String sellerIncomeAmount; + + /** + * 实发快递渠道 + */ + @JsonProperty("chosen_channel") + private String chosenChannel; + + /** + * 批次号 + */ + @JsonProperty("batch_id") + private String batchId; + + /** + * 生产日期 + */ + @JsonProperty("produced_date") + private String producedDate; + + /** + * 被合并被拆分的订单内部单号 + */ + @JsonProperty("link_o_id") + private String linkOId; + + /** + * 合并线上订单号 + */ + @JsonProperty("merge_so_id") + private String mergeSoId; + + /** + * 买家指定物流 + */ + @JsonProperty("shipment") + private String shipment; + + /** + * 预计送达时间 + */ + @JsonProperty("sign_time") + private String signTime; + + /** + * 跨境线下订单财务数据 + */ + @JsonProperty("cb_finances") + private String cbFinances; + + /** + * 订单明细扩展字段 + */ + @JsonProperty("tem_ext_data") + private String temExtData; + + /** + * discount_rate + */ + @JsonProperty("discount_rate") + private String discountRate; + + /** + * tag + */ + @JsonProperty("tag") + private String tag; + + /** + * amount + */ + @JsonProperty("amount") + private String amount; + + /** + * is_split + */ + @JsonProperty("is_split") + private String isSplit; + + /** + * is_merge + */ + @JsonProperty("is_merge") + private String isMerge; + + /** + * glasses + */ + @JsonProperty("glasses") + private String glasses; + + /** + * outer_as_id + */ + @JsonProperty("outer_as_id") + private String outerAsId; + + /** + * outer_so_id + */ + @JsonProperty("outer_so_id") + private String outerSoId; + + /** + * ext_datas + */ + @JsonProperty("ext_datas") + private String extDatas; + + /** + * __raw_so_ids__ + */ + @JsonProperty("__raw_so_ids__") + private List rawSoIds; + + /** + * raw_so_id + */ + @JsonProperty("raw_so_id") + private String rawSoId; + + /** + * drp_from + */ + @JsonProperty("drp_from") + private String drpFrom; + + /** + * drp_to + */ + @JsonProperty("drp_to") + private String drpTo; + + @Getter + @Setter + public static class PayBean { + + /** + * 是否支付 + */ + @JsonProperty("is_order_pay") + private Boolean isOrderPay; + + /** + * 支付帐号 + */ + @JsonProperty("buyer_account") + private String buyerAccount; + + /** + * 支付金额 + */ + @JsonProperty("amount") + private BigDecimal amount; + + /** + * 支付时间 + */ + @JsonProperty("pay_date") + private String payDate; + + /** + * 外部支付单号 + */ + @JsonProperty("outer_pay_id") + private String outerPayId; + + /** + * 支付单ID + */ + @JsonProperty("pay_id") + private String payId; + + /** + * 支付渠道 + */ + @JsonProperty("payment") + private String payment; + } + + @Getter + @Setter + public static class ItemDO { + + /** + * 是否赠品 + */ + @JsonProperty("is_gift") + private Boolean isGift; + + /** + * 商家编码,对应库存管理的 SKU + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 申请退款的状态 , 未申请:none;退款中:waiting;退款成功:success + */ + @JsonProperty("refund_status") + private String refundStatus; + + /** + * 退款的唯一单号 + */ + @JsonProperty("refund_id") + private String refundId; + + /** + * 单价 + */ + @JsonProperty("price") + private String price; + + /** + * 子订单号,最长不超过 50 + */ + @JsonProperty("outer_oi_id") + private String outerOiId; + + /** + * 商品状态 + */ + @JsonProperty("item_status") + private String itemStatus; + + /** + * 款式编码 + */ + @JsonProperty("i_id") + private String iId; + + /** + * 属性 + */ + @JsonProperty("properties_value") + private String propertiesValue; + + /** + * 子订单号,最长不超过 20 + */ + @JsonProperty("oi_id") + private Long oiId; + + /** + * 总额 + */ + @JsonProperty("amount") + private String amount; + + /** + * 外部sku_id + */ + @JsonProperty("shop_sku_id") + private String shopSkuId; + + /** + * 原始线上单号 + */ + @JsonProperty("raw_so_id") + private String rawSoId; + + /** + * 数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 是否预售 + */ + @JsonProperty("is_presale") + private String isPresale; + + /** + * 基本售价 + */ + @JsonProperty("base_price") + private String basePrice; + + /** + * 商品图片 + */ + @JsonProperty("pic") + private String pic; + + /** + * 商品类型 + */ + @JsonProperty("sku_type") + private String skuType; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseDO.java new file mode 100644 index 00000000..e2e127be --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseDO.java @@ -0,0 +1,178 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.purchase; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class PurchaseDO { + + @Schema(description = "采购日期") + @JsonProperty("po_date") + private String poDate; + + @Schema(description = "采购单号") + @JsonProperty("po_id") + private Long poId; + + @Schema(description = "外部订单号") + @JsonProperty("so_id") + private String soId; + + @Schema(description = "备注") + @JsonProperty("remark") + private String remark; + + @Schema(description = "状态:Creating:草拟,WaitConfirm:待审核,Confirmed:已确认,WaitDeliver:待发货,WaitReceive:待收货," + + "Finished:完成,Archive:归档,Cancelled:作废") + @JsonProperty("status") + private String status; + + @Schema(description = "供应商id") + @JsonProperty("supplier_id") + private Long supplierId; + + @Schema(description = "供应商名称") + @JsonProperty("seller") + private String seller; + + @Schema(description = "税率") + @JsonProperty("tax_rate") + private BigDecimal taxRate; + + @Schema(description = "采购员") + @JsonProperty("purchaser_name") + private String purchaserName; + + @Schema(description = "送货地址") + @JsonProperty("send_address") + private String sendAddress; + + @Schema(description = "合同条款") + @JsonProperty("term") + private String term; + + @Schema(description = "商品类型") + @JsonProperty("item_type") + private String itemType; + + @Schema(description = "商品集合") + private List items; + + @Schema(description = "多表现") + @JsonProperty("labels") + private String labels; + + @Schema(description = "审核生效日期") + @JsonProperty("confirm_date") + private String confirmDate; + + @Schema(description = "完成日期") + @JsonProperty("finish_time") + private String finishTime; + + @Schema(description = "仓库编号") + @JsonProperty("wms_co_id") + private Long wmsCoId; + + @Schema(description = "收货状态(Timeout:预计收货超时;Received:全部入库;Part_Received:部分入库;Not_Received:未入库)") + @JsonProperty("receive_status") + private String receiveStatus; + + @Schema(description = "溢装比") + @JsonProperty("more_rate") + private BigDecimal moreRate; + + @Schema(description = "物流公司名称") + @JsonProperty("logistics_company") + private String logisticsCompany; + + @Schema(description = "物流单号") + @JsonProperty("l_id") + private String lId; + + @Schema(description = "运费") + @JsonProperty("freight") + private BigDecimal freight; + + @Schema(description = "修改时间") + @JsonProperty("modified") + private String modified; + + @JsonProperty("receiver_name") + private String receiverName; + + @JsonProperty("wms_co_name") + private String wmsCoName; + + @JsonProperty("payment_method") + private String paymentMethod; + + @JsonProperty("receiver_phone") + private String receiverPhone; + + @Data + public static class ItemDO { + + @Schema(description = "商家sku") + @JsonProperty("sku_id") + private String skuId; + + @Schema(description = "商品名称") + @JsonProperty("name") + private String name; + + @Schema(description = "数量") + @JsonProperty("qty") + private Integer qty; + + @Schema(description = "单价") + @JsonProperty("price") + private BigDecimal price; + + @Schema(description = "款号") + @JsonProperty("i_id") + private String iId; + + @Schema(description = "采购单编号") + @JsonProperty("po_id") + private Long poId; + + @Schema(description = "采购单明细编号") + @JsonProperty("poi_id") + private Long poiId; + + @Schema(description = "交货日期") + @JsonProperty("delivery_date") + private String deliveryDate; + + @Schema(description = "备注") + @JsonProperty("remark") + private String remark; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseinDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseinDO.java new file mode 100644 index 00000000..61bae6c5 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseinDO.java @@ -0,0 +1,295 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.purchase; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; +import java.util.Map; + +@Getter +@Setter +public class PurchaseinDO { + + /** + * 入库单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 数据库行版本号:https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/rowversion-transact-sql?view=sql-server-ver16 + */ + @JsonProperty("ts") + private Long ts; + + /** + * 仓库名称 + */ + @JsonProperty("warehouse") + private String warehouse; + + /** + * 采购单号 + */ + @JsonProperty("po_id") + private Long poId; + + /** + * 供应商编号 + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 供应商名称 + */ + @JsonProperty("supplier_name") + private String supplierName; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 线上单号 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 外部单号 + */ + @JsonProperty("out_io_id") + private String outIoId; + + /** + * 状态 + */ + @JsonProperty("status") + private String status; + + /** + * 单据日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 仓库编号;主仓=1,销退仓=2, 进货仓=3,次品仓 = 4 + */ + @JsonProperty("wh_id") + private String whId; + + /** + * 分仓编号 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 税率 + */ + @JsonProperty("tax_rate") + private BigDecimal taxRate; + + /** + * 多标签 + */ + @JsonProperty("labels") + private String labels; + + /** + * 财务审核日期 + */ + @JsonProperty("archived") + private String archived; + + /** + * 预约单号 + */ + @JsonProperty("merge_so_id") + private String mergeSoId; + + /** + * 进仓类型 + */ + @JsonProperty("type") + private String type; + + /** + * 制单人 + */ + @JsonProperty("creator_name") + private String creatorName; + + /** + * 商品集合 + */ + private List items; + + /** + * 批次集合,获取该节点系统中相关业务项需配置 + */ + private List batchs; + + /** + * 唯一码集合,获取该节点系统中相关业务项需配置 + */ + private List sns; + + /** + * 财审状态,WaitConfirm=待审核;Confirmed=已审核 + */ + @JsonProperty("f_status") + private String fStatus; + + /** + * 物流单号 + */ + @JsonProperty("l_id") + private String lId; + + @Getter + @Setter + public static class ItemDO { + + /** + * 入库子单号 + */ + @JsonProperty("ioi_id") + private Long ioiId; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 商品名称 + */ + @JsonProperty("name") + private String name; + + /** + * 入库数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 入库单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 单价 + */ + @JsonProperty("cost_price") + private BigDecimal costPrice; + + /** + * 金额 + */ + @JsonProperty("cost_amount") + private BigDecimal costAmount; + + /** + * 商品明细备注 + */ + @JsonProperty("remark") + private String remark; + } + + @Getter + @Setter + public static class BatchDO { + + /** + * 批次号 + */ + @JsonProperty("batch_no") + private String batchNo; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 数量 + */ + @JsonProperty("qty") + private Integer qty; + + /** + * 批次日期 + */ + @JsonProperty("product_date") + private String productDate; + + /** + * 供应商编号 + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 供应商名称 + */ + @JsonProperty("supplier_name") + private String supplierName; + + /** + * 有效期至 + */ + @JsonProperty("expiration_date") + private String expirationDate; + } + + @Getter + @Setter + public static class SnDO { + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + /** + * 唯一码 + */ + @JsonProperty("sn") + private String sn; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseoutDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseoutDO.java new file mode 100644 index 00000000..d786b16e --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/PurchaseoutDO.java @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.purchase; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +public class PurchaseoutDO { + + /** + * 入库单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 退货日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 状态(Confirmed:生效,WaitConfirm:待审核,Creating:草拟,Cancelled:作废,OuterConfirming:外部确认中,Delete:取消) + */ + @JsonProperty("status") + private String status; + + /** + * 线上单号 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 财审状态,WaitConfirm=待审核;Confirmed=已审核 + */ + @JsonProperty("f_status") + private String fStatus; + + /** + * 仓库名 + */ + @JsonProperty("warehouse") + private String warehouse; + + /** + * 收货人/供应商名称 + */ + @JsonProperty("receiver_name") + private String receiverName; + + /** + * 收货电话 + */ + @JsonProperty("receiver_mobile") + private String receiverMobile; + + /** + * 收件人省 + */ + @JsonProperty("receiver_state") + private String receiverState; + + /** + * 收件人市 + */ + @JsonProperty("receiver_city") + private String receiverCity; + + /** + * 收件人区 + */ + @JsonProperty("receiver_district") + private String receiverDistrict; + + /** + * 收件人省地址 + */ + @JsonProperty("receiver_address") + private String receiverAddress; + + /** + * 仓库编号;主仓=1,销退仓=2, 进货仓=3,次品仓 = 4 + */ + @JsonProperty("wh_id") + private Integer whId; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 采购单号 + */ + @JsonProperty("po_id") + private Long poId; + + /** + * 分仓编号 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 供应商ID + */ + @JsonProperty("seller_id") + private Long sellerId; + + /** + * 标记|多标签 + */ + @JsonProperty("labels") + private String labels; + + /** + * 物流公司 + */ + @JsonProperty("logistics_company") + private String logisticsCompany; + + /** + * 物流公司编号 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 物流单号 + */ + @JsonProperty("l_id") + private String lId; + + /** + * 财务审核日期 + */ + @JsonProperty("archived") + private String archived; + + /** + * 创建人 + */ + @JsonProperty("creator_name") + private String creatorName; + + /** + * 虚拟仓编号 + */ + @JsonProperty("lock_wh_id") + private String lockWhId; + + /** + * 虚拟仓名称 + */ + @JsonProperty("lock_wh_name") + private String lockWhName; + + /** + * 外部单号 + */ + @JsonProperty("out_io_id") + private String outIoId; + + /** + * 商品集合 + */ + @JsonProperty("items") + private List items; + + /** + * 批次集合,获取该节点系统中相关业务项需配置 + */ + @JsonProperty("batchs") + private List batchs; + + /** + * 唯一码集合,获取该节点系统中相关业务项需配置 + */ + @JsonProperty("sns") + private List sns; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/SupplierDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/SupplierDO.java new file mode 100644 index 00000000..41db9500 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/purchase/SupplierDO.java @@ -0,0 +1,100 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.purchase; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class SupplierDO { + + /** + * 供应商ID + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 供应商代码 + */ + @JsonProperty("supplier_code") + private String supplierCode; + + /** + * 名称 + */ + @JsonProperty("name") + private String name; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 备注1 + */ + @JsonProperty("remark") + private String remark; + + /** + * 备注2 + */ + @JsonProperty("remark2") + private String remark2; + + /** + * 备注3 + */ + @JsonProperty("remark3") + private String remark3; + + /** + * 供应商分类 + */ + @JsonProperty("group") + private String group; + + /** + * 是否启用,true:启用,false:未启用 + */ + @JsonProperty("enabled") + private String enabled; + + /** + * 开户银行 + */ + @JsonProperty("depositbank") + private String depositbank; + + /** + * 账户名称 + */ + @JsonProperty("bankacount") + private String bankacount; + + /** + * 银行账号 + */ + @JsonProperty("acountnumber") + private String acountnumber; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/AllocateDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/AllocateDO.java new file mode 100644 index 00000000..50e7d3c4 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/AllocateDO.java @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.refund; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class AllocateDO { + + /** + * 分仓编号,调拨出为发起方,调拨入为接收方 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 公司编号 + */ + @JsonProperty("co_id") + private Long coId; + + /** + * 调拨单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 单据日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * Creating:待确认,Confirmed:调拨中,完成(若remark包含”红冲单据“则ERP显示红冲状态),Picking:拣货中,OuterConfirming:外部确认中,Cancelled:取消,Confirming:确认 + */ + @JsonProperty("status") + private String status; + + /** + * 调拨出仓库名称(对应ERP仓库资料设定页面) + */ + @JsonProperty("warehouse") + private String warehouse; + + /** + * 调拨入仓库名称(对应ERP仓库资料设定页面) + */ + @JsonProperty("link_warehouse") + private String linkWarehouse; + + /** + * 财务状态Archive:归档,modifing:变更,WaitConfirm:待审核,Confirmed:已审核,Cancelled:取消,Delete:作废 + */ + @JsonProperty("f_status") + private String fStatus; + + /** + * 调拨类型 + */ + @JsonProperty("type") + private String type; + + /** + * 调拨出仓库编号;主仓=1,销退仓=2,进货仓=3,次品仓=4 + */ + @JsonProperty("wh_id") + private Long whId; + + /** + * 调拨入仓库编号;主仓=1,销退仓=2,进货仓=3,次品仓=4 + */ + @JsonProperty("link_wh_id") + private Long linkWhId; + + /** + * 调拨入分仓编号,调拨出为接收方,调拨入为发起方 + */ + @JsonProperty("link_wms_co_id") + private Long linkWmsCoId; + + /** + * 调拨单号 + */ + @JsonProperty("link_io_id") + private Long linkIoId; + + /** + * 调拨建议号,跨仓调拨入单据才有值,数据来源是跨仓调拨上传的so_id + */ + @JsonProperty("so_id") + private String soId; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 标记|多标签 + */ + @JsonProperty("labels") + private List labels; + + /** + * 商品集合 + */ + @JsonProperty("items") + private List items; + + /** + * 批次集合,获取该节点系统中相关业务项需配置(对应erp基础设置开启生产批次管理 如果是分仓数据 分仓也需要开启) + */ + @JsonProperty("batchs") + private List batchs; + + /** + * 唯一码集合,获取该节点系统中相关业务项需配置 + */ + @JsonProperty("sns") + private List sns; + + /** + * 收货人 + */ + @JsonProperty("receiver_name_en") + private String receiverNameEn; + + /** + * 移动电话 + */ + @JsonProperty("receiver_mobile_en") + private String receiverMobileEn; + + /** + * 省 + */ + @JsonProperty("receiver_state") + private String receiverState; + + /** + * 市 + */ + @JsonProperty("receiver_city") + private String receiverCity; + + /** + * 区 + */ + @JsonProperty("receiver_district") + private String receiverDistrict; + + /** + * 地址 + */ + @JsonProperty("receiver_address") + private String receiverAddress; + + /** + * 物流单号 + */ + @JsonProperty("l_id") + private String lId; + + /** + * 快递公司编码 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 物流公司名称 + */ + @JsonProperty("logistics_company") + private String logisticsCompany; + + /** + * 单位 + */ + @JsonProperty("unit") + private String unit; + + /** + * 调出虚拟仓编码 + */ + @JsonProperty("lock_wh_id") + private String lockWhId; + + /** + * 调入虚拟仓编码 + */ + @JsonProperty("lock_link_wh_id") + private String lockLinkWhId; + + /** + * 外部单号 + */ + @JsonProperty("out_io_id") + private String outIoId; + +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/InoutWaterDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/InoutWaterDO.java new file mode 100644 index 00000000..c5740860 --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/InoutWaterDO.java @@ -0,0 +1,155 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.refund; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +public class InoutWaterDO { + + /** + * 公司编号,调拨业务时代表发起方 + */ + @JsonProperty("co_id") + private Long coId; + + /** + * 分仓编号,调拨业务时代表接收方 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 仓库编号,主仓=1,销退仓=2,进货仓=3,次品仓=4 + */ + @JsonProperty("wh_id") + private Long whId; + + /** + * 调入/出仓的仓库编号,主仓=1,销退仓=2,进货仓=3,次品仓=4调拨业务 + */ + @JsonProperty("link_wh_id") + private Long linkWhId; + + /** + * 调入/出仓单号,调拨业务 + */ + @JsonProperty("link_io_id") + private Long linkIoId; + + /** + * 店铺编号 + */ + @JsonProperty("shop_id") + private Long shopId; + + /** + * 进出仓单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 内部单号 + */ + @JsonProperty("o_id") + private Long oId; + + /** + * 线上单号,订单业务 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 进出仓日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 供应商ID,采购相关业务 + */ + @JsonProperty("supplier_id") + private Long supplierId; + + /** + * 状态 + */ + @JsonProperty("status") + private String status; + + /** + * 是否使用库存 + */ + @JsonProperty("stock_enabled") + private String stockEnabled; + + /** + * 预估重量 + */ + @JsonProperty("weight") + private BigDecimal weight; + + /** + * 实际重量 + */ + @JsonProperty("f_weight") + private BigDecimal fWeight; + + /** + * 出库类型,其它出入库业务 + */ + @JsonProperty("drp_co_name") + private String drpCoName; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 商品集合 + */ + @JsonProperty("items") + private List items; + + /** + * 单据类型 + */ + @JsonProperty("type") + private String type; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/OtherInoutDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/OtherInoutDO.java new file mode 100644 index 00000000..659c973b --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/OtherInoutDO.java @@ -0,0 +1,208 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.refund; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class OtherInoutDO { + + /** + * 出仓单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * 单据日期 + */ + @JsonProperty("io_date") + private String ioDate; + + /** + * 单据状态,Confirmed生效,WaitConfirm待审核,OuterConfirming外部确认中,Cancelled取消(单据生效后的作废),Delete作废(单据生效前的作废) + */ + @JsonProperty("status") + private String status; + + /** + * 线上单号 + */ + @JsonProperty("so_id") + private String soId; + + /** + * 单据类型 + */ + @JsonProperty("type") + private String type; + + /** + * 财务状态 + */ + @JsonProperty("f_status") + private String fStatus; + + /** + * 仓库名称 + */ + @JsonProperty("warehouse") + private String warehouse; + + /** + * 收货人 + */ + @JsonProperty("receiver_name") + private String receiverName; + + /** + * 收货人手机 + */ + @JsonProperty("receiver_mobile") + private String receiverMobile; + + /** + * 收货人省 + */ + @JsonProperty("receiver_state") + private String receiverState; + + /** + * 收货人市 + */ + @JsonProperty("receiver_city") + private String receiverCity; + + /** + * 收货人区 + */ + @JsonProperty("receiver_district") + private String receiverDistrict; + + /** + * 收货人地址 + */ + @JsonProperty("receiver_address") + private String receiverAddress; + + /** + * 仓库编号;主仓=1,销退仓=2,进货仓=3,次品仓=4,自定义1仓=6,自定义2仓=7,自定义3仓=8 + */ + @JsonProperty("wh_id") + private Long whId; + + /** + * 备注 + */ + @JsonProperty("remark") + private String remark; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 多标签 + */ + @JsonProperty("labels") + private String labels; + + /** + * 分仓编号 + */ + @JsonProperty("wms_co_id") + private Long wmsCoId; + + /** + * 创建人 + */ + @JsonProperty("creator_name") + private String creatorName; + + /** + * 出库类型 + */ + @JsonProperty("drp_co_name") + private String drpCoName; + + /** + * 其它出入库人员 + */ + @JsonProperty("inout_user") + private String inoutUser; + + /** + * 快递单号 + */ + @JsonProperty("l_id") + private String lId; + + /** + * 物流公司编码 + */ + @JsonProperty("lc_id") + private String lcId; + + /** + * 物流公司 + */ + @JsonProperty("logistics_company") + private String logisticsCompany; + + /** + * 虚拟仓编码 + */ + @JsonProperty("lock_wh_id") + private Long lockWhId; + + /** + * 虚拟仓名称 + */ + @JsonProperty("lock_wh_name") + private String lockWhName; + + /** + * 商品集合 + */ + @JsonProperty("items") + private List items; + + /** + * 批次集合,获取该节点系统中相关业务项需配置(对应erp基础设置开启生产批次管理 如果是分仓数据 分仓也需要开启) + */ + @JsonProperty("batchs") + private List batchs; + + /** + * 唯一码集合,获取该节点系统中相关业务项需配置(对应erp基础设置商品唯一码开关) + */ + @JsonProperty("sns") + private List sns; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/RefundSingleDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/RefundSingleDO.java new file mode 100644 index 00000000..20c7156c --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/RefundSingleDO.java @@ -0,0 +1,387 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.refund; + +import com.fasterxml.jackson.annotation.JsonProperty; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.List; + +@Getter +@Setter +public class RefundSingleDO { + + @Schema(description = "ERP售后单号") + @JsonProperty("as_id") + private Long asId; + + @Schema(description = "申请时间") + @JsonProperty("as_date") + private String asDate; + + @Schema(description = "平台退货退款单号") + @JsonProperty("outer_as_id") + private String outerAsId; + + @Schema(description = "内部单号") + @JsonProperty("o_id") + private Long oId; + + @Schema(description = "线上单号") + @JsonProperty("so_id") + private String soId; + + @Schema(description = "售后类型,普通退货,其它,拒收退货,仅退款,投诉,补发,换货") + @JsonProperty("type") + private String type; + + @Schema(description = "登记时间") + @JsonProperty("created") + private String created; + + @Schema(description = "修改时间") + @JsonProperty("modified") + private String modified; + + @Schema(description = "状态(WaitConfirm:待确认,Confirmed:已确认,Cancelled:作废,Merged:被合并)") + @JsonProperty("status") + private String status; + + @Schema(description = "WAIT_SELLER_AGREE:买家已经申请退款,等待卖家同意,WAIT_BUYER_RETURN_GOODS:卖家已经同意退款,等待买家退货," + + "WAIT_SELLER_CONFIRM_GOODS:买家已经退货,等待卖家确认收货,SELLER_REFUSE_BUYER:卖家拒绝退款,CLOSED:退款关闭,SUCCESS:退款成功") + @JsonProperty("shop_status") + private String shopStatus; + + @Schema(description = "备注") + @JsonProperty("remark") + private String remark; + + @Schema(description = "问题类型") + @JsonProperty("question_type") + private String questionType; + + @Schema(description = "仓库") + @JsonProperty("warehouse") + private String warehouse; + + @Schema(description = "退款金额") + @JsonProperty("refund") + private BigDecimal refund; + + @Schema(description = "补偿金额") + @JsonProperty("payment") + private BigDecimal payment; + + @Schema(description = "货物状态(BUYER_NOT_RECEIVED:买家未收到货,BUYER_RECEIVED:买家已收到货,BUYER_RETURNED_GOODS:买家已退货," + + "SELLER_RECEIVED:卖家已收到退货)") + @JsonProperty("good_status") + private String goodStatus; + + @Schema(description = "售后线下备注") + @JsonProperty("node") + private String node; + + @Schema(description = "原订单状态") + @JsonProperty("order_status") + private String orderStatus; + + @Schema(description = "店铺编号") + @JsonProperty("shop_id") + private Long shopId; + + @Schema(description = "物流公司") + @JsonProperty("logistics_company") + private String logisticsCompany; + + @Schema(description = "物流单号") + @JsonProperty("l_id") + private String lId; + + @Schema(description = "仓库编号") + @JsonProperty("wh_id") + private Long whId; + + @Schema(description = "分仓id") + @JsonProperty("wms_co_id") + private Long wmsCoId; + + @Schema(description = "最后确认日期") + @JsonProperty("confirm_date") + private String confirmDate; + + @Schema(description = "卖家应退运费") + @JsonProperty("freight") + private BigDecimal freight; + + @Schema(description = "分销商编号") + @JsonProperty("drp_co_id_from") + private Long drpCoIdFrom; + + @Schema(description = "收件人电话") + @JsonProperty("receiver_mobile") + private String receiverMobile; + + @Schema(description = "收件人名称") + @JsonProperty("receiver_name") + private String receiverName; + + @Schema(description = "买家账号") + @JsonProperty("shop_buyer_id") + private String shopBuyerId; + + @Schema(description = "商品集合") + private List items; + + @Schema(description = "批次集合") + private List batchs; + + @Schema(description = "sn码集合") + private List sns; + + @Schema(description = "供销商编号") + @JsonProperty("drp_co_id_to") + private Long drpCoIdTo; + + @Schema(description = "退款版本号") + @JsonProperty("refund_version") + private Long refundVersion; + + @Schema(description = "多标签") + private String labels; + + @Schema(description = "店铺名称") + @JsonProperty("shop_name") + private String shopName; + + @JsonProperty("creator_name") + private String creatorName; + + @JsonProperty("modifier_name") + private String modifierName; + + /** + * 出库单号 + */ + @JsonProperty("io_id") + private Long ioId; + + /** + * order_type + */ + @JsonProperty("order_type") + private String orderType; + + /** + * buyer_apply_refund + */ + @JsonProperty("buyer_apply_refund") + private String buyerApplyRefund; + + /** + * ts + */ + @JsonProperty("ts") + private Long ts; + + /** + * refund_phase + */ + @JsonProperty("refund_phase") + private String refundPhase; + + /** + * 币种 + */ + @JsonProperty("currency") + private String currency; + + /** + * is_split + */ + @JsonProperty("is_split") + private String isSplit; + + /** + * is_merge + */ + @JsonProperty("is_merge") + private String isMerge; + + /** + * shop_freight + */ + @JsonProperty("shop_freight") + private String shopFreight; + + /** + * 店铺站点信息 + */ + @JsonProperty("shop_site") + private String shopSite; + + /** + * shop_type + */ + @JsonProperty("shop_type") + private String shopType; + + /** + * result + */ + @JsonProperty("result") + private String result; + + /** + * order_labels + */ + @JsonProperty("order_labels") + private List orderLabels; + + /** + * 优惠/差额 + */ + @JsonProperty("free_amount") + private String freeAmount; + + @Getter + @Setter + public static class ItemDO { + + @Schema(description = "售后子单号") + @JsonProperty("asi_id") + private Long asiId; + + @Schema(description = "ERP售后单号") + @JsonProperty("as_id") + private Long asId; + + @Schema(description = "商品编码") + @JsonProperty("sku_id") + private String skuId; + + @Schema(description = "数量") + @JsonProperty("qty") + private Integer qty; + + @Schema(description = "单价") + @JsonProperty("price") + private BigDecimal price; + + @Schema(description = "金额") + @JsonProperty("amount") + private BigDecimal amount; + + @Schema(description = "商品名称") + @JsonProperty("name") + private String name; + + @Schema(description = "商品图片地址") + @JsonProperty("pic") + private String pic; + + @Schema(description = "类型(退货,换货,补发)") + @JsonProperty("type") + private String type; + + @Schema(description = "颜色规格") + @JsonProperty("properties_value") + private String propertiesValue; + + @Schema(description = "子订单号") + @JsonProperty("outer_oi_id") + private String outerOiId; + + @Schema(description = "商品类型") + @JsonProperty("sku_type") + private String skuType; + + @Schema(description = "实际退货数量") + @JsonProperty("r_qty") + private Integer rQty; + + @Schema(description = "入仓时间") + @JsonProperty("receive_date") + private String receiveDate; + + @Schema(description = "组合商品编码") + @JsonProperty("combine_sku_id") + private String combineSkuId; + + @Schema(description = "店铺商品编码") + @JsonProperty("shop_sku_id") + private String shopSkuId; + + @Schema(description = "款式编码") + @JsonProperty("i_id") + private String iId; + + @Schema(description = "次品数量") + @JsonProperty("defective_qty") + private Long defectiveQty; + } + + @Getter + @Setter + public static class BatchDO { + + @Schema(description = "批次号") + @JsonProperty("batch_no") + private String batchNo; + + @Schema(description = "商品编码") + @JsonProperty("sku_id") + private String skuId; + + @Schema(description = "商品数量") + @JsonProperty("qty") + private Integer qty; + + @Schema(description = "批次日期") + @JsonProperty("product_date") + private String productDate; + + @Schema(description = "供应商编号") + @JsonProperty("supplier_id") + private Long supplierId; + + @Schema(description = "供应商名称") + @JsonProperty("supplier_name") + private String supplierName; + + @Schema(description = "有效期至") + @JsonProperty("expiration_date") + private String expirationDate; + } + + @Getter + @Setter + public static class SnDO { + + @Schema(description = "商品编码") + @JsonProperty("sku_id") + private String skuId; + + @Schema(description = "SN号码") + @JsonProperty("sn") + private String sn; + } +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/TrackinfoDO.java b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/TrackinfoDO.java new file mode 100644 index 00000000..8a3d73ef --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/carp-module-http-remote-jst/src/main/java/cn/sliew/carp/module/http/sync/remote/jst/response/refund/TrackinfoDO.java @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.module.http.sync.remote.jst.response.refund; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class TrackinfoDO { + + /** + * 第几条 + */ + @JsonProperty("auto_id") + private Long autoId; + + /** + * 公司编号 + */ + @JsonProperty("co_idc") + private Long coIdc; + + /** + * 物流单号 + */ + @JsonProperty("l_id") + private String lId; + + /** + * 商品编码 + */ + @JsonProperty("sku_id") + private String skuId; + + /** + * 唯一码 + */ + @JsonProperty("sku_sn") + private String skuSn; + + /** + * 状态;1=发货 + */ + @JsonProperty("status") + private String status; + + /** + * 创建时间 + */ + @JsonProperty("created") + private String created; + + /** + * 创建人 + */ + @JsonProperty("creator") + private String creator; + + /** + * 修改时间 + */ + @JsonProperty("modified") + private String modified; + + /** + * 修改人 + */ + @JsonProperty("modifier") + private String modifier; +} diff --git a/carp-modules/carp-module-http-sync/carp-module-http-remote/pom.xml b/carp-modules/carp-module-http-sync/carp-module-http-remote/pom.xml new file mode 100644 index 00000000..e0ac361c --- /dev/null +++ b/carp-modules/carp-module-http-sync/carp-module-http-remote/pom.xml @@ -0,0 +1,37 @@ + + + + + 4.0.0 + + cn.sliew + carp-module-http-sync + 0.0.13-SNAPSHOT + ../pom.xml + + carp-module-http-remote + pom + + + carp-module-http-remote-feign + carp-module-http-remote-jst + + + \ No newline at end of file diff --git a/carp-modules/carp-module-export/pom.xml b/carp-modules/carp-module-http-sync/pom.xml similarity index 81% rename from carp-modules/carp-module-export/pom.xml rename to carp-modules/carp-module-http-sync/pom.xml index ad7b7861..ad232553 100644 --- a/carp-modules/carp-module-export/pom.xml +++ b/carp-modules/carp-module-http-sync/pom.xml @@ -23,9 +23,16 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml - carp-module-export + carp-module-http-sync + pom + + + carp-module-http-framework + carp-module-http-job + carp-module-http-remote + \ No newline at end of file diff --git a/carp-modules/carp-module-kubernetes/pom.xml b/carp-modules/carp-module-kubernetes/pom.xml index 58f19eec..5ce9990f 100644 --- a/carp-modules/carp-module-kubernetes/pom.xml +++ b/carp-modules/carp-module-kubernetes/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-kubernetes diff --git a/carp-modules/carp-module-persistence/carp-module-persistence-api/pom.xml b/carp-modules/carp-module-persistence/carp-module-persistence-api/pom.xml index e2beddb6..ce35dc5e 100644 --- a/carp-modules/carp-module-persistence/carp-module-persistence-api/pom.xml +++ b/carp-modules/carp-module-persistence/carp-module-persistence-api/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-persistence - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-persistence-api diff --git a/carp-modules/carp-module-persistence/pom.xml b/carp-modules/carp-module-persistence/pom.xml index 5e6fbdda..b0333c5f 100644 --- a/carp-modules/carp-module-persistence/pom.xml +++ b/carp-modules/carp-module-persistence/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-persistence diff --git a/carp-modules/carp-module-plugin/pom.xml b/carp-modules/carp-module-plugin/pom.xml index 1c9b5109..41ff9f3c 100644 --- a/carp-modules/carp-module-plugin/pom.xml +++ b/carp-modules/carp-module-plugin/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-plugin diff --git a/carp-modules/carp-module-queue/carp-module-queue-api/pom.xml b/carp-modules/carp-module-queue/carp-module-queue-api/pom.xml index 32957deb..36a16d25 100644 --- a/carp-modules/carp-module-queue/carp-module-queue-api/pom.xml +++ b/carp-modules/carp-module-queue/carp-module-queue-api/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-queue - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-queue-api diff --git a/carp-modules/carp-module-queue/carp-module-queue-redis/pom.xml b/carp-modules/carp-module-queue/carp-module-queue-redis/pom.xml index eeb376c7..a24146b6 100644 --- a/carp-modules/carp-module-queue/carp-module-queue-redis/pom.xml +++ b/carp-modules/carp-module-queue/carp-module-queue-redis/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-queue - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-queue-redis diff --git a/carp-modules/carp-module-queue/pom.xml b/carp-modules/carp-module-queue/pom.xml index d31f8bc7..8be291ae 100644 --- a/carp-modules/carp-module-queue/pom.xml +++ b/carp-modules/carp-module-queue/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-queue diff --git a/carp-modules/carp-module-resource/pom.xml b/carp-modules/carp-module-resource/pom.xml index f49f2f22..de3dc6cf 100644 --- a/carp-modules/carp-module-resource/pom.xml +++ b/carp-modules/carp-module-resource/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-resource diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/pom.xml b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/pom.xml index 056aa1b9..14ed197a 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/pom.xml +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-scheduler - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-scheduler-base diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobConfig.java b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobConfig.java index 92e910ea..49c80727 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobConfig.java +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobConfig.java @@ -27,7 +27,7 @@ import lombok.Data; @Data -@TableName("schedule_job_config") +@TableName("carp_schedule_job_config") public class ScheduleJobConfig extends BaseAuditDO { @TableField("job_group_id") diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobGroup.java b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobGroup.java index 115da5a2..b1595ebb 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobGroup.java +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobGroup.java @@ -24,7 +24,7 @@ import lombok.Data; @Data -@TableName("schedule_job_group") +@TableName("carp_schedule_job_group") public class ScheduleJobGroup extends BaseAuditDO { @TableField("namespace") diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobInstance.java b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobInstance.java index f8861e8a..9a22f798 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobInstance.java +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/java/cn/sliew/carp/module/scheduler/repository/entity/ScheduleJobInstance.java @@ -26,7 +26,7 @@ import java.util.Date; @Data -@TableName("schedule_job_instance") +@TableName("carp_schedule_job_instance") public class ScheduleJobInstance extends BaseAuditDO { @TableField("job_config_id") diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobConfigMapper.xml b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobConfigMapper.xml index c0634aa5..3889fada 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobConfigMapper.xml +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobConfigMapper.xml @@ -53,7 +53,7 @@ diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobInstanceMapper.xml b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobInstanceMapper.xml index abbadaa6..a750d4cf 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobInstanceMapper.xml +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-base/src/main/resources/cn/sliew/carp/module/scheduler/repository/mapper/ScheduleJobInstanceMapper.xml @@ -54,7 +54,7 @@ diff --git a/carp-modules/carp-module-scheduler/carp-module-scheduler-quartz/pom.xml b/carp-modules/carp-module-scheduler/carp-module-scheduler-quartz/pom.xml index 13d3c1a4..c388e2cf 100644 --- a/carp-modules/carp-module-scheduler/carp-module-scheduler-quartz/pom.xml +++ b/carp-modules/carp-module-scheduler/carp-module-scheduler-quartz/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-scheduler - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-scheduler-quartz diff --git a/carp-modules/carp-module-scheduler/pom.xml b/carp-modules/carp-module-scheduler/pom.xml index a6791ab8..faf629ce 100644 --- a/carp-modules/carp-module-scheduler/pom.xml +++ b/carp-modules/carp-module-scheduler/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-scheduler diff --git a/carp-modules/carp-module-security/carp-module-security-core/pom.xml b/carp-modules/carp-module-security/carp-module-security-core/pom.xml index cd5a5da8..05248174 100644 --- a/carp-modules/carp-module-security/carp-module-security-core/pom.xml +++ b/carp-modules/carp-module-security/carp-module-security-core/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-security - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-security-core diff --git a/carp-modules/carp-module-security/carp-module-security-sa-token/pom.xml b/carp-modules/carp-module-security/carp-module-security-sa-token/pom.xml index 634eca16..ff5f8e7d 100644 --- a/carp-modules/carp-module-security/carp-module-security-sa-token/pom.xml +++ b/carp-modules/carp-module-security/carp-module-security-sa-token/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-security - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-security-sa-token diff --git a/carp-modules/carp-module-security/carp-module-security-spring/pom.xml b/carp-modules/carp-module-security/carp-module-security-spring/pom.xml index e1b355d8..1cf13534 100644 --- a/carp-modules/carp-module-security/carp-module-security-spring/pom.xml +++ b/carp-modules/carp-module-security/carp-module-security-spring/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-security - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-security-spring diff --git a/carp-modules/carp-module-security/pom.xml b/carp-modules/carp-module-security/pom.xml index 213a9167..e7a94115 100644 --- a/carp-modules/carp-module-security/pom.xml +++ b/carp-modules/carp-module-security/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-security diff --git a/carp-modules/carp-module-system/pom.xml b/carp-modules/carp-module-system/pom.xml index 10c1fd88..46edff18 100644 --- a/carp-modules/carp-module-system/pom.xml +++ b/carp-modules/carp-module-system/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-system diff --git a/carp-modules/carp-module-workflow/carp-module-workflow-api/pom.xml b/carp-modules/carp-module-workflow/carp-module-workflow-api/pom.xml index ee82fb6e..d008f311 100644 --- a/carp-modules/carp-module-workflow/carp-module-workflow-api/pom.xml +++ b/carp-modules/carp-module-workflow/carp-module-workflow-api/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-workflow - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-workflow-api diff --git a/carp-modules/carp-module-workflow/carp-module-workflow-internal/pom.xml b/carp-modules/carp-module-workflow/carp-module-workflow-internal/pom.xml index bdd8b9d3..0149e6d7 100644 --- a/carp-modules/carp-module-workflow/carp-module-workflow-internal/pom.xml +++ b/carp-modules/carp-module-workflow/carp-module-workflow-internal/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-module-workflow - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-workflow-internal diff --git a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowInstanceEventDispatcher.java b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowInstanceEventDispatcher.java index b7a1b82d..21920022 100644 --- a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowInstanceEventDispatcher.java +++ b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowInstanceEventDispatcher.java @@ -19,13 +19,14 @@ package cn.sliew.carp.module.workflow.internal.engine.dispatch; import cn.sliew.carp.framework.common.dict.workflow.WorkflowInstanceEvent; +import cn.sliew.carp.framework.common.serder.SerDer; +import cn.sliew.carp.framework.common.serder.jdk.JdkSerDerFactory; import cn.sliew.carp.module.queue.api.Message; import cn.sliew.carp.module.queue.api.MessageHandler; import cn.sliew.carp.module.queue.api.MessageListener; -import cn.sliew.carp.module.queue.api.util.Serder; import cn.sliew.carp.module.workflow.api.engine.dispatch.WorkflowInstanceEventDispatcher; -import cn.sliew.carp.module.workflow.api.engine.dispatch.handler.WorkflowInstanceEventHandler; import cn.sliew.carp.module.workflow.api.engine.dispatch.event.WorkflowInstanceStatusEvent; +import cn.sliew.carp.module.workflow.api.engine.dispatch.handler.WorkflowInstanceEventHandler; import cn.sliew.carp.module.workflow.internal.engine.dispatch.event.WorkflowInstanceEventDTO; import cn.sliew.carp.module.workflow.internal.statemachine.WorkflowTaskInstanceStateMachine; import lombok.extern.slf4j.Slf4j; @@ -38,6 +39,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; @Slf4j @@ -75,9 +77,9 @@ public void destroy() throws Exception { @Override public void handler(Message message) throws Exception { if (message.getBody() != null) { - Object deserialized = Serder.deserializeByJava(message.getBody()); - if (deserialized instanceof WorkflowInstanceEventDTO) { - WorkflowInstanceEventDTO eventDTO = (WorkflowInstanceEventDTO) deserialized; + SerDer serDer = JdkSerDerFactory.INSTANCE.getInstance(); + WorkflowInstanceEventDTO eventDTO = serDer.deserialize(message.getBody(), WorkflowInstanceEventDTO.class); + if (Objects.nonNull(eventDTO)) { dispatch(eventDTO); } } diff --git a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowTaskInstanceEventDispatcher.java b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowTaskInstanceEventDispatcher.java index 7973fb16..ed1b2a13 100644 --- a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowTaskInstanceEventDispatcher.java +++ b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/InternalWorkflowTaskInstanceEventDispatcher.java @@ -19,10 +19,11 @@ package cn.sliew.carp.module.workflow.internal.engine.dispatch; import cn.sliew.carp.framework.common.dict.workflow.WorkflowTaskInstanceEvent; +import cn.sliew.carp.framework.common.serder.SerDer; +import cn.sliew.carp.framework.common.serder.jdk.JdkSerDerFactory; import cn.sliew.carp.module.queue.api.Message; import cn.sliew.carp.module.queue.api.MessageHandler; import cn.sliew.carp.module.queue.api.MessageListener; -import cn.sliew.carp.module.queue.api.util.Serder; import cn.sliew.carp.module.workflow.api.engine.dispatch.WorkflowTaskInstanceEventDispatcher; import cn.sliew.carp.module.workflow.api.engine.dispatch.event.WorkflowTaskInstanceStatusEvent; import cn.sliew.carp.module.workflow.api.engine.dispatch.handler.WorkflowTaskInstanceEventHandler; @@ -38,6 +39,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.CompletableFuture; @Slf4j @@ -75,9 +77,9 @@ public void destroy() throws Exception { @Override public void handler(Message message) throws Exception { if (message.getBody() != null) { - Object deserialized = Serder.deserializeByJava(message.getBody()); - if (deserialized instanceof WorkflowTaskInstanceEventDTO) { - WorkflowTaskInstanceEventDTO eventDTO = (WorkflowTaskInstanceEventDTO) deserialized; + SerDer serDer = JdkSerDerFactory.INSTANCE.getInstance(); + WorkflowTaskInstanceEventDTO eventDTO = serDer.deserialize(message.getBody(), WorkflowTaskInstanceEventDTO.class); + if (Objects.nonNull(eventDTO)) { dispatch(eventDTO); } } diff --git a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowInstanceEventPublisher.java b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowInstanceEventPublisher.java index 7f827958..3bec744b 100644 --- a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowInstanceEventPublisher.java +++ b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowInstanceEventPublisher.java @@ -18,10 +18,11 @@ package cn.sliew.carp.module.workflow.internal.engine.dispatch.publisher; +import cn.sliew.carp.framework.common.serder.SerDer; +import cn.sliew.carp.framework.common.serder.jdk.JdkSerDerFactory; import cn.sliew.carp.module.queue.api.Message; import cn.sliew.carp.module.queue.api.Queue; import cn.sliew.carp.module.queue.api.QueueFactory; -import cn.sliew.carp.module.queue.api.util.Serder; import cn.sliew.carp.module.workflow.api.engine.dispatch.event.WorkflowInstanceStatusEvent; import cn.sliew.carp.module.workflow.api.engine.dispatch.publisher.WorkflowInstanceEventPublisher; import cn.sliew.carp.module.workflow.internal.engine.dispatch.InternalWorkflowInstanceEventDispatcher; @@ -44,9 +45,10 @@ public void publish(WorkflowInstanceStatusEvent event) { WorkflowInstanceEventDTO eventDTO = (WorkflowInstanceEventDTO) event; Queue queue = queueFactory.get(InternalWorkflowInstanceEventDispatcher.TOPIC); + SerDer serDer = JdkSerDerFactory.INSTANCE.getInstance(); Message message = Message.builder() .topic(queue.getName()) - .body(Serder.serializeByJava(eventDTO)) + .body(serDer.serialize(eventDTO)) .build(); queue.push(message); } diff --git a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowTaskInstanceEventPublisher.java b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowTaskInstanceEventPublisher.java index ff5d113a..584554f6 100644 --- a/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowTaskInstanceEventPublisher.java +++ b/carp-modules/carp-module-workflow/carp-module-workflow-internal/src/main/java/cn/sliew/carp/module/workflow/internal/engine/dispatch/publisher/InternalWorkflowTaskInstanceEventPublisher.java @@ -18,10 +18,11 @@ package cn.sliew.carp.module.workflow.internal.engine.dispatch.publisher; +import cn.sliew.carp.framework.common.serder.SerDer; +import cn.sliew.carp.framework.common.serder.jdk.JdkSerDerFactory; import cn.sliew.carp.module.queue.api.Message; import cn.sliew.carp.module.queue.api.Queue; import cn.sliew.carp.module.queue.api.QueueFactory; -import cn.sliew.carp.module.queue.api.util.Serder; import cn.sliew.carp.module.workflow.api.engine.dispatch.event.WorkflowTaskInstanceStatusEvent; import cn.sliew.carp.module.workflow.api.engine.dispatch.publisher.WorkflowTaskInstanceEventPublisher; import cn.sliew.carp.module.workflow.internal.engine.dispatch.InternalWorkflowTaskInstanceEventDispatcher; @@ -44,9 +45,10 @@ public void publish(WorkflowTaskInstanceStatusEvent event) { WorkflowTaskInstanceEventDTO eventDTO = (WorkflowTaskInstanceEventDTO) event; Queue queue = queueFactory.get(InternalWorkflowTaskInstanceEventDispatcher.TOPIC); + SerDer serDer = JdkSerDerFactory.INSTANCE.getInstance(); Message message = Message.builder() .topic(queue.getName()) - .body(Serder.serializeByJava(eventDTO)) + .body(serDer.serialize(eventDTO)) .build(); queue.push(message); } diff --git a/carp-modules/carp-module-workflow/pom.xml b/carp-modules/carp-module-workflow/pom.xml index d1096ba0..5210d26c 100644 --- a/carp-modules/carp-module-workflow/pom.xml +++ b/carp-modules/carp-module-workflow/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-modules - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-module-workflow diff --git a/carp-modules/pom.xml b/carp-modules/pom.xml index d9206b72..45109795 100644 --- a/carp-modules/pom.xml +++ b/carp-modules/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT carp-modules pom @@ -32,7 +32,8 @@ carp-module-alert carp-module-application carp-module-datasource - carp-module-export + carp-module-excel + carp-module-http-sync carp-module-kubernetes carp-module-persistence carp-module-plugin diff --git a/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-api/pom.xml b/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-api/pom.xml index 5a2822d0..c60f614b 100644 --- a/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-api/pom.xml +++ b/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-api/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugin-schedule - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-schedule-api diff --git a/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-quartz/pom.xml b/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-quartz/pom.xml index be8a9046..6c4e1a97 100644 --- a/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-quartz/pom.xml +++ b/carp-plugins/carp-plugin-schedule/carp-plugin-schedule-quartz/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugin-schedule - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-schedule-quartz diff --git a/carp-plugins/carp-plugin-schedule/pom.xml b/carp-plugins/carp-plugin-schedule/pom.xml index 0df6d9c2..04048671 100644 --- a/carp-plugins/carp-plugin-schedule/pom.xml +++ b/carp-plugins/carp-plugin-schedule/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugins - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-schedule diff --git a/carp-plugins/carp-plugin-test/carp-plugin-test-1/pom.xml b/carp-plugins/carp-plugin-test/carp-plugin-test-1/pom.xml index 09422bfe..5f4a1354 100644 --- a/carp-plugins/carp-plugin-test/carp-plugin-test-1/pom.xml +++ b/carp-plugins/carp-plugin-test/carp-plugin-test-1/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugin-test - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-test-1 diff --git a/carp-plugins/carp-plugin-test/carp-plugin-test-2/pom.xml b/carp-plugins/carp-plugin-test/carp-plugin-test-2/pom.xml index ff815a95..97fa8bda 100644 --- a/carp-plugins/carp-plugin-test/carp-plugin-test-2/pom.xml +++ b/carp-plugins/carp-plugin-test/carp-plugin-test-2/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugin-test - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-test-2 diff --git a/carp-plugins/carp-plugin-test/carp-plugin-test-api/pom.xml b/carp-plugins/carp-plugin-test/carp-plugin-test-api/pom.xml index ad50aa60..ccd25338 100644 --- a/carp-plugins/carp-plugin-test/carp-plugin-test-api/pom.xml +++ b/carp-plugins/carp-plugin-test/carp-plugin-test-api/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugin-test - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-test-api diff --git a/carp-plugins/carp-plugin-test/pom.xml b/carp-plugins/carp-plugin-test/pom.xml index e5d72706..feac4857 100644 --- a/carp-plugins/carp-plugin-test/pom.xml +++ b/carp-plugins/carp-plugin-test/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-plugins - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugin-test diff --git a/carp-plugins/pom.xml b/carp-plugins/pom.xml index f98456ec..464d9cd1 100644 --- a/carp-plugins/pom.xml +++ b/carp-plugins/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-plugins diff --git a/carp-server/pom.xml b/carp-server/pom.xml index 46091038..47acff79 100644 --- a/carp-server/pom.xml +++ b/carp-server/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT carp-server @@ -42,11 +42,11 @@ ${project.parent.groupId} - carp-module-application-vela + carp-module-datasource ${project.parent.groupId} - carp-module-datasource + carp-module-http-job ${project.parent.groupId} diff --git a/carp-server/src/main/resources/application-dev.yml b/carp-server/src/main/resources/application-dev.yml index 4b54044f..e2b8369e 100644 --- a/carp-server/src/main/resources/application-dev.yml +++ b/carp-server/src/main/resources/application-dev.yml @@ -16,11 +16,35 @@ # spring: - datasource.carp: - driver-class-name: com.mysql.cj.jdbc.Driver - jdbc-url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/carp?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useAffectedRows=true - username: ${MYSQL_USERNAME:root} - password: ${MYSQL_PASSWORD:123456} + datasource: + carp: + minimum-idle: 1 + maximum-pool-size: 5 + auto-commit: true + idle-timeout: 600000 + pool-name: carp + max-lifetime: 900000 + connection-timeout: 10000 + connection-test-query: SELECT 1 + validation-timeout: 1000 + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/carp?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useAffectedRows=true + username: ${MYSQL_USERNAME:root} + password: ${MYSQL_PASSWORD:123456} + dataservice: + minimum-idle: 1 + maximum-pool-size: 5 + auto-commit: true + idle-timeout: 600000 + pool-name: data-service + max-lifetime: 900000 + connection-timeout: 10000 + connection-test-query: SELECT 1 + validation-timeout: 1000 + driver-class-name: com.mysql.cj.jdbc.Driver + jdbc-url: jdbc:mysql://${MYSQL_HOST:127.0.0.1}:${MYSQL_PORT:3306}/data_service?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&useAffectedRows=true + username: ${MYSQL_USERNAME:root} + password: ${MYSQL_PASSWORD:123456} quartz: properties: org.quartz: diff --git a/carp-support/carp-annotation-processor/pom.xml b/carp-support/carp-annotation-processor/pom.xml new file mode 100644 index 00000000..30152aed --- /dev/null +++ b/carp-support/carp-annotation-processor/pom.xml @@ -0,0 +1,42 @@ + + + + + 4.0.0 + + cn.sliew + carp-support + 0.0.13-SNAPSHOT + ../pom.xml + + carp-annotation-processor + + + + com.google.auto.service + auto-service + + + com.palantir.javapoet + javapoet + + + + \ No newline at end of file diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java new file mode 100644 index 00000000..aab5baa6 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpAnnotationProcessor.java @@ -0,0 +1,79 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor; + +import cn.sliew.carp.support.annotation.processor.plugins.web.WebPlugin; +import com.google.auto.common.BasicAnnotationProcessor; +import com.google.auto.service.AutoService; +import com.google.common.collect.Lists; +import com.palantir.javapoet.JavaFile; + +import javax.annotation.processing.*; +import javax.lang.model.element.TypeElement; +import javax.tools.Diagnostic; +import java.io.IOException; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * 参考 lombok.core.AnnotationProcessor + * + * @see BasicAnnotationProcessor + */ +@SupportedAnnotationTypes("*") +@AutoService(Processor.class) +public class CarpAnnotationProcessor extends AbstractProcessor { + + private List registered = Lists.newArrayList(); + private List active = Lists.newArrayList(); + + @Override + public synchronized void init(ProcessingEnvironment processingEnv) { + super.init(processingEnv); + registered.add(new WebPlugin()); + active = registered.stream().filter(plugin -> plugin.support(processingEnv)).collect(Collectors.toList()); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + try { + processInternal(annotations, roundEnv); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Exception occurred %s".formatted(e)); + } + return false; + } + + protected void processInternal(Set annotations, RoundEnvironment roundEnv) { + active.stream().map(plugin -> plugin.process(roundEnv.getElementsAnnotatedWith(plugin.supported()), roundEnv)) + .flatMap(Collection::stream) + .forEach(this::writeFile); + } + + private void writeFile(JavaFile javaFile) { + try { + javaFile.writeTo(processingEnv.getFiler()); + } catch (IOException e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Failed to write definition %s".formatted(javaFile)); + } + } + +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java new file mode 100644 index 00000000..d37c32bd --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/CarpProcessorPlugin.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor; + +import com.google.auto.common.BasicAnnotationProcessor; +import com.palantir.javapoet.JavaFile; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.Element; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.Set; + +/** + * 参考 lombok.core.AnnotationProcessor.ProcessorDescriptor + * @see BasicAnnotationProcessor.Step + */ +public interface CarpProcessorPlugin { + + boolean support(ProcessingEnvironment processingEnv); + + Class supported(); + + Collection process(Set annotated, RoundEnvironment roundEnv); + +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java new file mode 100644 index 00000000..1324792c --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractClassGeneratePlugin.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins; + +import cn.sliew.carp.support.annotation.processor.util.ProcessingEnvUtils; +import com.palantir.javapoet.JavaFile; +import com.palantir.javapoet.TypeSpec; + +import javax.lang.model.element.ExecutableElement; + +/** + * 生成一个新的类,实现特定接口。 + * Annotation Processor 只能实现编译时获取特定的注解标记的类, + * 获取到之后生成新的类和修改已有的类已经超出了 Annotation Processor 的功能。 + * 当需要新生成类时可以使用 javapoet 等工具,生成新的 .java 文件 + * 修改已有的类则需要使用 javac,这是 java 的内部类。目前没有相关的库可以辅助生成, + * 做的比较好的也就是 lombok。参考:https://stackoverflow.com/a/70008734 + */ +public abstract class AbstractClassGeneratePlugin extends AbstractProcessorPlugin { + + @Override + protected JavaFile getJavaFile(ElementMethod elementMethod, IndexedValue indexedValue) { + var annotedMethod = indexedValue.value(); + var typeSpec = createType(elementMethod, indexedValue, annotedMethod); + String packageName = ProcessingEnvUtils.getPackageName(processingEnv, annotedMethod); + return JavaFile.builder(packageName, typeSpec).build(); + } + + protected abstract TypeSpec createType(ElementMethod elementMethod, IndexedValue indexedValue, ExecutableElement handlerMethod); + +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java new file mode 100644 index 00000000..0edf87ca --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/AbstractProcessorPlugin.java @@ -0,0 +1,112 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins; + +import cn.sliew.carp.support.annotation.processor.CarpProcessorPlugin; +import com.palantir.javapoet.JavaFile; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.annotation.processing.RoundEnvironment; +import javax.lang.model.element.AnnotationMirror; +import javax.lang.model.element.Element; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.util.ElementFilter; +import javax.tools.Diagnostic; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.annotation.Annotation; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 生成一个新的类,实现特定接口 + */ +public abstract class AbstractProcessorPlugin implements CarpProcessorPlugin { + + protected ProcessingEnvironment processingEnv; + + @Override + public boolean support(ProcessingEnvironment processingEnv) { + this.processingEnv = processingEnv; + return false; + } + + public abstract Class supported(); + + @Override + public Collection process(Set annotated, RoundEnvironment roundEnv) { + Map> nameDataListMap = ElementFilter + .methodsIn(annotated) + .stream() + .collect(Collectors.groupingBy(ElementMethod::new)); + + return nameDataListMap + .entrySet() + .stream() + .flatMap(entry -> handle(entry.getKey(), entry.getValue())) + .toList(); + } + + + private Stream handle(ElementMethod elementMethod, List handlers) { + return handlers.stream() + .map(IndexedValue.indexed()) + .map(element -> handle(elementMethod, element)); + } + + private JavaFile handle(ElementMethod elementMethod, IndexedValue indexedValue) { + try { + return getJavaFile(elementMethod, indexedValue); + } catch (Exception e) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage(), indexedValue.value()); + throw e; + } + } + + protected abstract JavaFile getJavaFile(ElementMethod elementMethod, IndexedValue indexedValue); + + protected void log(String msg) { + if (processingEnv.getOptions().containsKey("debug")) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, msg); + } + } + + protected void error(String msg, Element element) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, element); + } + + protected void error(String msg, Element element, AnnotationMirror annotation) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, msg, element, annotation); + } + + protected void fatalError(Exception e) { + // We don't allow exceptions of any kind to propagate to the compiler + StringWriter writer = new StringWriter(); + e.printStackTrace(new PrintWriter(writer)); + fatalError(writer.toString()); + } + + protected void fatalError(String msg) { + processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "FATAL ERROR: " + msg); + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/ElementMethod.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/ElementMethod.java new file mode 100644 index 00000000..81319bd5 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/ElementMethod.java @@ -0,0 +1,15 @@ +package cn.sliew.carp.support.annotation.processor.plugins; + +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Name; +import javax.lang.model.element.TypeElement; + +public record ElementMethod(TypeElement typeElement, Name annotatedMethodName) { + ElementMethod(ExecutableElement element) { + this((TypeElement) element.getEnclosingElement(), element.getSimpleName()); + } + + public String toMethodName(int index) { + return "%s$%s$%d$Generated".formatted(typeElement.getSimpleName().toString(), annotatedMethodName.toString(), index); + } +} \ No newline at end of file diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/IndexedValue.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/IndexedValue.java new file mode 100644 index 00000000..63f9161c --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/IndexedValue.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins; + +import java.util.function.Function; + +public record IndexedValue(int index, T value) { + static Function> indexed() { + return new Function<>() { + int index = 1; + + @Override + public IndexedValue apply(T t) { + return new IndexedValue(index++, t); + } + }; + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java new file mode 100644 index 00000000..339b671e --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HandlerWriter.java @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +import cn.sliew.carp.support.annotation.processor.specs.GeneratedMethodSpecs; +import cn.sliew.carp.support.annotation.processor.util.ElementUtil; +import com.palantir.javapoet.*; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Types; +import java.util.List; +import java.util.Objects; + +class HandlerWriter { + + private static final String CONTROLLER = "controller"; + + private ExecutableElement httpMethodElement; + private ExecutableElement produceElement; + private ExecutableElement processElement; + private ExecutableElement pathElement; + private Types typeUtils; + private TypeMirror requestType; + + HandlerWriter(ProcessingEnvironment processingEnv) { + this.typeUtils = processingEnv.getTypeUtils(); + var handlerInterfaceElement = processingEnv.getElementUtils().getTypeElement(RequestHandler.class.getCanonicalName()); + if (Objects.nonNull(handlerInterfaceElement)) { + this.httpMethodElement = ElementUtil.getMethodElement(handlerInterfaceElement, "method"); + this.produceElement = ElementUtil.getMethodElement(handlerInterfaceElement, "produce"); + this.processElement = ElementUtil.getMethodElement(handlerInterfaceElement, "process"); + this.pathElement = ElementUtil.getMethodElement(handlerInterfaceElement, "path"); + this.requestType = processingEnv.getElementUtils() + .getTypeElement(Request.class.getCanonicalName()) + .asType(); + } + } + + private static MethodSpec constructor(TypeName typeName) { + return MethodSpec.constructorBuilder() + .addParameter(ParameterSpec.builder(typeName, CONTROLLER).build()) + .addCode("this.%s = %s;".formatted(CONTROLLER, CONTROLLER)) + .build(); + } + + TypeSpec buildHandler(String handlerMethodName, ExecutableElement handler, TypeName typeName, RequestHandle annotation) { + return TypeSpec.classBuilder(handlerMethodName) + .addField(FieldSpec.builder(typeName, CONTROLLER, Modifier.FINAL, Modifier.PRIVATE).build()) + .addMethod(constructor(typeName)) +// .addAnnotation(Generated.class) + .addSuperinterface(TypeName.get(RequestHandler.class)) + .addModifiers(Modifier.FINAL) + .addMethods(List.of( + produce(annotation.produce()), + path(annotation.value()), + method(annotation.method()), + process(handler) + )) + .build(); + } + + private MethodSpec method(HttpMethod httpMethod) { + return GeneratedMethodSpecs.generatedOverrideMethodSpec(httpMethodElement, + CodeBlock.builder() + .add("return $T.$L;", httpMethod.getClass(), httpMethod.toString()) + .build() + ); + } + + private MethodSpec path(String value) { + return GeneratedMethodSpecs.generatedOverrideMethodSpec(pathElement, + CodeBlock.builder() + .add("return $S;", value) + .build() + ); + } + + private MethodSpec produce(String produce) { + return GeneratedMethodSpecs.generatedOverrideMethodSpec(produceElement, + CodeBlock.builder() + .add("return $S;", produce) + .build() + ); + } + + private MethodSpec process(ExecutableElement handlerMethod) { + var controllerCall = controllerCall(handlerMethod, handlerMethod.getParameters()); + TypeKind handlerMethodType = handlerMethod.getReturnType().getKind(); + return handlerMethodType == TypeKind.VOID + ? voidMethod(controllerCall) + : valueReturningMethod(controllerCall); + } + + private MethodSpec valueReturningMethod(CodeBlock controllerCall) { + return MethodSpec.overriding(processElement) + .addStatement("return $L", controllerCall) + .build(); + } + + private MethodSpec voidMethod(CodeBlock controllerCall) { + return MethodSpec.overriding(processElement) + .addStatement(controllerCall) + .addStatement("return $T.noContent()", Response.class) + .build(); + } + + private CodeBlock controllerCall(ExecutableElement handlerMethod, List parameters) { + if (parameters.size() > 1 || !doesParamTypesMatchRequest(parameters)) { + throw new RuntimeException("Too many parameters or type of param is not Request"); + } + return GeneratedMethodSpecs.generatedMethodCallSpec(parameters, CONTROLLER, handlerMethod); + } + + private boolean doesParamTypesMatchRequest(List parameters) { + var requestType = this.requestType; + return parameters.stream().map(VariableElement::asType) + .allMatch(paramType -> typeUtils.isSameType(paramType, requestType)); + } +} \ No newline at end of file diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HttpMethod.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HttpMethod.java new file mode 100644 index 00000000..0576564a --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/HttpMethod.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +public enum HttpMethod { + DELETE, GET, PATCH, POST, PUT +} \ No newline at end of file diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/MediaType.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/MediaType.java new file mode 100644 index 00000000..ebe6d2de --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/MediaType.java @@ -0,0 +1,29 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +public class MediaType { + + public static final String APPLICATION_JSON = "application/json"; + public static final String TEXT_PLAIN = "text/plain"; + + private MediaType() { + } + +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/Request.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/Request.java new file mode 100644 index 00000000..551a8289 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/Request.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +public interface Request { + String body(); +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/RequestHandle.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/RequestHandle.java new file mode 100644 index 00000000..415b941b --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/RequestHandle.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.SOURCE) +@Target(ElementType.METHOD) +public @interface RequestHandle { + + HttpMethod method(); + + String value() default "/"; + + String produce() default MediaType.APPLICATION_JSON; +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/RequestHandler.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/RequestHandler.java new file mode 100644 index 00000000..0a03a151 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/RequestHandler.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +public interface RequestHandler { + + HttpMethod method(); + + String produce(); + + String path(); + + Object process(Request request) throws Exception; + +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/Response.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/Response.java new file mode 100644 index 00000000..d984baf1 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/Response.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +public interface Response { + static Response noContent() { + return new Response() { + @Override + public int statusCode() { + return 204; + } + + @Override + public String body() { + return null; + } + }; + } + + int statusCode(); + + String body(); +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java new file mode 100644 index 00000000..7519866b --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/plugins/web/WebPlugin.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.plugins.web; + +import cn.sliew.carp.support.annotation.processor.plugins.AbstractClassGeneratePlugin; +import cn.sliew.carp.support.annotation.processor.plugins.IndexedValue; +import cn.sliew.carp.support.annotation.processor.plugins.ElementMethod; +import com.palantir.javapoet.TypeName; +import com.palantir.javapoet.TypeSpec; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.ExecutableElement; +import java.lang.annotation.Annotation; + +public class WebPlugin extends AbstractClassGeneratePlugin { + + private HandlerWriter handlerWriter; + + @Override + public boolean support(ProcessingEnvironment processingEnv) { + super.support(processingEnv); + this.handlerWriter = new HandlerWriter(processingEnv); + return false; + } + + @Override + public Class supported() { + return RequestHandle.class; + } + + @Override + protected TypeSpec createType(ElementMethod elementMethod, IndexedValue indexedValue, ExecutableElement handlerMethod) { + return handlerWriter.buildHandler( + elementMethod.toMethodName(indexedValue.index()), + handlerMethod, + TypeName.get(handlerMethod.getEnclosingElement().asType()), + handlerMethod.getAnnotation(RequestHandle.class) + ); + } + +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java new file mode 100644 index 00000000..596abde2 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedMethodSpecs.java @@ -0,0 +1,47 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.specs; + +import com.palantir.javapoet.CodeBlock; +import com.palantir.javapoet.MethodSpec; + +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.Name; +import javax.lang.model.element.VariableElement; +import java.util.List; + +public enum GeneratedMethodSpecs { + ; + + public static MethodSpec generatedOverrideMethodSpec(ExecutableElement overrideMethod, CodeBlock methodBody) { + return MethodSpec.overriding(overrideMethod) + .addCode(methodBody) + .build(); + } + + public static CodeBlock generatedMethodCallSpec(List parameters, String callObject, ExecutableElement callMethod) { + var methodCallParams = parameters.stream().map(VariableElement::getSimpleName).map(Name::toString) + .findFirst() + .map(__ -> "(arg0)") + .orElse("()"); + return CodeBlock.builder() + .add(callObject + ".$L$L", callMethod.getSimpleName().toString(), methodCallParams) + .build(); + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java new file mode 100644 index 00000000..87e89ef4 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/specs/GeneratedTryCatchSpecs.java @@ -0,0 +1,30 @@ +package cn.sliew.carp.support.annotation.processor.specs; + +import com.palantir.javapoet.CodeBlock; + +public enum GeneratedTryCatchSpecs { + ; + + public static CodeBlock tryClause(CodeBlock methodCall, CodeBlock catchClause) { + return CodeBlock.builder() + .beginControlFlow("try") + .add(methodCall) + .endControlFlow() + .add(catchClause) + .build(); + } + + public static CodeBlock catchClause(CodeBlock exceptionCall) { + return CodeBlock.builder() + .beginControlFlow("catch ($T e)", Exception.class) + .beginControlFlow("try") + .addStatement(exceptionCall) + .endControlFlow() + .beginControlFlow("catch ($T innerException)", Exception.class) + .addStatement("throw new $T(innerException)", RuntimeException.class) + .endControlFlow() + .addStatement("throw new $T(e)", RuntimeException.class) + .endControlFlow() + .build(); + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ElementUtil.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ElementUtil.java new file mode 100644 index 00000000..4346fd29 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ElementUtil.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.util; + +import javax.lang.model.element.ExecutableElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.util.ElementFilter; + +public enum ElementUtil { + ; + + public static ExecutableElement getMethodElement(TypeElement typeElement, String elementName) { + return ElementFilter.methodsIn(typeElement.getEnclosedElements()).stream() + .filter(it -> it.getSimpleName().toString().equals(elementName)) + .findFirst() + .get(); + } +} diff --git a/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ProcessingEnvUtils.java b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ProcessingEnvUtils.java new file mode 100644 index 00000000..60f00c00 --- /dev/null +++ b/carp-support/carp-annotation-processor/src/main/java/cn/sliew/carp/support/annotation/processor/util/ProcessingEnvUtils.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package cn.sliew.carp.support.annotation.processor.util; + +import javax.annotation.processing.ProcessingEnvironment; +import javax.lang.model.element.Element; +import javax.lang.model.element.PackageElement; + +public enum ProcessingEnvUtils { + ; + + public static String getPackageName(ProcessingEnvironment processingEnvironment, Element element) { + return getPackageElement(processingEnvironment, element).getQualifiedName().toString(); + } + + public static PackageElement getPackageElement(ProcessingEnvironment processingEnvironment, Element element) { + return processingEnvironment.getElementUtils().getPackageOf(element); + } + +} diff --git a/carp-support/carp-generator/pom.xml b/carp-support/carp-generator/pom.xml index 1b4e1cb9..69d5302c 100644 --- a/carp-support/carp-generator/pom.xml +++ b/carp-support/carp-generator/pom.xml @@ -23,7 +23,7 @@ cn.sliew carp-support - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-generator diff --git a/carp-support/pom.xml b/carp-support/pom.xml index 517ac7a4..0bb15592 100644 --- a/carp-support/pom.xml +++ b/carp-support/pom.xml @@ -23,13 +23,14 @@ cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT ../pom.xml carp-support pom + carp-annotation-processor carp-generator diff --git a/pom.xml b/pom.xml index bcf3881e..08c2a67f 100644 --- a/pom.xml +++ b/pom.xml @@ -21,7 +21,7 @@ 4.0.0 cn.sliew carp - 0.0.12-SNAPSHOT + 0.0.13-SNAPSHOT pom carp Carp Framwork @@ -68,13 +68,13 @@ + carp-dist + carp-examples carp-framework + carp-modules carp-plugins carp-server carp-support - carp-modules - carp-dist - carp-examples @@ -130,6 +130,10 @@ 6.9.2 7.6.1 0.5.1 + 3.3.2 + 0.0.9 + 9.7 + 0.5.0 @@ -229,6 +233,26 @@ carp-module-datasource ${project.version} + + ${project.groupId} + carp-module-http-framework + ${project.version} + + + ${project.groupId} + carp-module-http-job + ${project.version} + + + ${project.groupId} + carp-module-http-remote-feign + ${project.version} + + + ${project.groupId} + carp-module-http-remote-jst + ${project.version} + ${project.groupId} carp-module-kubernetes @@ -291,6 +315,12 @@ ${project.version} + + ${project.groupId} + carp-annotation-processor + ${project.version} + + ${project.groupId} carp-server @@ -602,6 +632,39 @@ javers-spring ${javers.version} + + + com.alibaba + easyexcel + ${easyexcel.version} + + + + com.tencent.devops + devops-boot-starter-service + ${bkdevops.version} + + + com.tencent.devops + devops-boot-starter-schedule-server + ${bkdevops.version} + + + com.tencent.devops + devops-boot-starter-schedule-worker + ${bkdevops.version} + + + + org.ow2.asm + asm + ${asm.version} + + + com.palantir.javapoet + javapoet + ${javapoet.version} + @@ -690,6 +753,7 @@ auto-service ${auto-service.version} + org.pf4j diff --git a/tools/docker/mongodb/docker-compose.yml b/tools/docker/mongodb/docker-compose.yml new file mode 100644 index 00000000..23d8c4d4 --- /dev/null +++ b/tools/docker/mongodb/docker-compose.yml @@ -0,0 +1,33 @@ +version: "3.8" + +services: + + mongo: + image: mongo:7.0.8 + container_name: mongo + environment: + - MONGO_INITDB_ROOT_USERNAME=root + - MONGO_INITDB_ROOT_PASSWORD=example + ports: + - 27017:27017 + restart: unless-stopped + networks: + - mongo + + mongo-express: + image: mongo-express:1.0.2-20 + container_name: mongo-express + environment: + - ME_CONFIG_MONGODB_ADMINUSERNAME=root + - ME_CONFIG_MONGODB_ADMINPASSWORD=example + - ME_CONFIG_MONGODB_URL=mongodb://root:example@mongo:27017/ + - ME_CONFIG_BASICAUTH=false + ports: + - 8081:8081 + restart: unless-stopped + networks: + - mongo + +networks: + mongo: + driver: bridge \ No newline at end of file diff --git a/tools/docker/mysql/init.d/carp-http-sync.sql b/tools/docker/mysql/init.d/carp-http-sync.sql new file mode 100644 index 00000000..cd82cc58 --- /dev/null +++ b/tools/docker/mysql/init.d/carp-http-sync.sql @@ -0,0 +1,21 @@ +create database if not exists carp default character set utf8mb4 collate utf8mb4_unicode_ci; +use carp; + +drop table if exists job_sync_offset; +create table `job_sync_offset` +( + `id` bigint not null auto_increment comment '自增主键', + `group` varchar(64) not null comment '任务分组', + `job` varchar(64) not null comment '任务', + `sub_job` varchar(64) not null comment '子任务', + `account` varchar(128) comment '账号', + `sub_account` varchar(128) comment '子账号', + `last_sync_offset` varchar(255) comment '上一次位点', + `sync_offset` varchar(255) comment '位点', + `creator` varchar(32) comment '创建人', + `create_time` datetime not null default current_timestamp comment '创建时间', + `editor` varchar(32) comment '修改人', + `update_time` datetime not null default current_timestamp on update current_timestamp comment '更新时间', + primary key (`id`), + unique key `uniq_job_account` (`group`,`job`,`sub_job`,`account`,`sub_account`) +) engine = innodb comment='任务 同步位点'; \ No newline at end of file diff --git a/tools/docker/mysql/init.d/carp-scheduler.sql b/tools/docker/mysql/init.d/carp-scheduler.sql index d3a91bd1..4833ee49 100644 --- a/tools/docker/mysql/init.d/carp-scheduler.sql +++ b/tools/docker/mysql/init.d/carp-scheduler.sql @@ -1,8 +1,8 @@ create database if not exists carp default character set utf8mb4 collate utf8mb4_unicode_ci; use carp; -DROP TABLE IF EXISTS `schedule_job_group`; -CREATE TABLE `schedule_job_group` +DROP TABLE IF EXISTS `carp_schedule_job_group`; +CREATE TABLE `carp_schedule_job_group` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `namespace` varchar(64) NOT NULL COMMENT '命名空间', @@ -16,11 +16,11 @@ CREATE TABLE `schedule_job_group` UNIQUE KEY `uniq_name` (`namespace`,`name`) ) ENGINE=InnoDB COMMENT='schedule job group'; -INSERT INTO `schedule_job_group` (`id`, `namespace`, `name`, `remark`, `creator`, `editor`) +INSERT INTO `carp_schedule_job_group` (`id`, `namespace`, `name`, `remark`, `creator`, `editor`) VALUES (1, 'default', 'default', NULL, 'sys', 'sys'); -DROP TABLE IF EXISTS `schedule_job_config`; -CREATE TABLE `schedule_job_config` +DROP TABLE IF EXISTS `carp_schedule_job_config`; +CREATE TABLE `carp_schedule_job_config` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `job_group_id` bigint(20) NOT NULL COMMENT '任务分组 id', @@ -38,12 +38,12 @@ CREATE TABLE `schedule_job_config` UNIQUE KEY `uniq_group_name` (`job_group_id`,`name`) ) ENGINE=InnoDB COMMENT='schedule job config'; -INSERT INTO `schedule_job_config` (`id`, `job_group_id`, `type`, `engine_type`, `job_type`, `name`, `handler`, `remark`, +INSERT INTO `carp_schedule_job_config` (`id`, `job_group_id`, `type`, `engine_type`, `job_type`, `name`, `handler`, `remark`, `creator`, `editor`) VALUES (1, 1, '0', 'internal', '0', 'demo', NULL, NULL, 'sys', 'sys'); -DROP TABLE IF EXISTS `schedule_job_instance`; -CREATE TABLE `schedule_job_instance` +DROP TABLE IF EXISTS `carp_schedule_job_instance`; +CREATE TABLE `carp_schedule_job_instance` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'ID', `job_config_id` bigint(20) NOT NULL COMMENT '任务配置id', @@ -64,15 +64,15 @@ CREATE TABLE `schedule_job_instance` PRIMARY KEY (`id`) ) ENGINE=InnoDB COMMENT='schedule job instance'; -INSERT INTO `schedule_job_instance` (`id`, `job_config_id`, `name`, `cron`, `timezone`, `start_time`, `end_time`, +INSERT INTO `carp_schedule_job_instance` (`id`, `job_config_id`, `name`, `cron`, `timezone`, `start_time`, `end_time`, `props`, `params`, `timeout`, `status`, `remark`, `creator`, `editor`) VALUES (1, 1, 'high', '0/10 * * * * ?', 'GMT+8', '2024-01-01 00:00:00', '9999-01-01 00:00:00', NULL, NULL, NULL, '0', NULL, 'sys', 'sys'); -INSERT INTO `schedule_job_instance` (`id`, `job_config_id`, `name`, `cron`, `timezone`, `start_time`, `end_time`, +INSERT INTO `carp_schedule_job_instance` (`id`, `job_config_id`, `name`, `cron`, `timezone`, `start_time`, `end_time`, `props`, `params`, `timeout`, `status`, `remark`, `creator`, `editor`) VALUES (2, 1, 'middle', '0 0/1 * * * ?', 'GMT+8', '2024-01-01 00:00:00', '9999-01-01 00:00:00', NULL, NULL, NULL, '0', NULL, 'sys', 'sys'); -INSERT INTO `schedule_job_instance` (`id`, `job_config_id`, `name`, `cron`, `timezone`, `start_time`, `end_time`, +INSERT INTO `carp_schedule_job_instance` (`id`, `job_config_id`, `name`, `cron`, `timezone`, `start_time`, `end_time`, `props`, `params`, `timeout`, `status`, `remark`, `creator`, `editor`) VALUES (3, 1, 'high', '0 0/5 * * * ?', 'GMT+8', '2024-01-01 00:00:00', '9999-01-01 00:00:00', NULL, NULL, NULL, '0', NULL, 'sys', 'sys'); diff --git a/tools/docker/mysql/init.d/data-service-jst.sql b/tools/docker/mysql/init.d/data-service-jst.sql new file mode 100644 index 00000000..820e16b8 --- /dev/null +++ b/tools/docker/mysql/init.d/data-service-jst.sql @@ -0,0 +1,130 @@ +create database if not exists data_service default character set utf8mb4 collate utf8mb4_unicode_ci; +use data_service; + +drop table if exists jst_auth; +create table `jst_auth` +( + `id` bigint not null auto_increment comment '自增主键', + `app_key` varchar(128) not null comment 'key', + `app_secret` varchar(128) not null comment 'secret', + `company` varchar(255) not null comment '公司名称', + `access_token` varchar(128) comment '访问令牌', + `refresh_token` varchar(128) comment '更新令牌', + `expires_in` bigint(20) comment 'access_token访问过期时间【单位是秒】,还有多少秒后过期', + `expires_date` datetime comment 'access_token访问过期日期', + `scope` varchar(64) comment '固定值:all', + `creator` varchar(32) comment '创建人', + `create_time` datetime not null default current_timestamp comment '创建时间', + `editor` varchar(32) comment '修改人', + `update_time` datetime not null default current_timestamp on update current_timestamp comment '更新时间', + primary key (`id`), + unique key `uniq_app` (`app_key`, `company`) +) engine = innodb comment='聚水潭 授权信息'; + +drop table if exists jst_order; +create table `jst_order` +( + `id` bigint not null auto_increment comment '自增主键', + `app_key` varchar(64) not null comment '聚水潭应用 key', + `company` varchar(255) not null comment '公司名称', + `is_cod` varchar(8) comment '是否货到付款', + `l_id` varchar(256) comment '快递单号', + `send_date` datetime comment '发货日期', + `pay_date` datetime comment '支付时间', + `freight` varchar(64) comment '运费,保留两位小数,单位(元)', + `receiver_address` text comment '收货地址', + `receiver_district` varchar(64) comment '区', + `wms_co_id` varchar(64) comment '发货仓编号', + `logistics_company` varchar(64) comment '快递公司', + `as_id` varchar(64) comment '补发换货单对应的售后单号', + `free_amount` varchar(64) comment '抵扣金额', + `shop_name` varchar(64) comment '店铺名称', + `question_type` varchar(64) comment '问题类型,仅当问题订单时有效', + `outer_pay_id` varchar(128) comment '外部支付单号', + `so_id` varchar(64) comment '线上订单号,最长不超过 20;唯一', + `type` varchar(64) comment '订单类型', + `order_from` varchar(64) comment '订单来源', + `status` varchar(64) comment '待付款:WaitPay;发货中:Delivering;被合并:Merged;异常:Question;被拆分:Split;等供销商|外仓发货:WaitOuterSent;已付款待审核:WaitConfirm;已客审待财审:WaitFConfirm;已发货:Sent;取消:Cancelled', + `pay_amount` varchar(64) comment '应付金额,保留两位小数,单位(元)', + `shop_buyer_id` text comment '买家昵称', + `open_id` varchar(128) comment '平台买家唯一值,仅支持抖音,快手,小红书', + `shop_status` varchar(64) comment '平台订单状态', + `receiver_mobile` text comment '手机', + `receiver_phone` varchar(128) comment '电话', + `order_date` datetime comment '下单时间', + `question_desc` varchar(64) comment '问题描述', + `receiver_city` varchar(64) comment '收件信息-市', + `receiver_state` varchar(64) comment '收件信息-省', + `receiver_name` mediumtext comment '收件信息-收件人', + `o_id` bigint(20) not null comment 'ERP 内部订单号,唯一', + `shop_id` bigint(20) comment '店铺编号', + `co_id` bigint(20) comment '公司编号', + `remark` text comment '订单备注;卖家备注', + `drp_co_id_from` varchar(64) comment '分销商编号', + `modified` datetime comment '修改时间', + `labels` varchar(256) comment '多标签', + `paid_amount` varchar(64) comment '实际支付金额', + `currency` varchar(64) comment '币种', + `buyer_message` text comment '买家留言', + `lc_id` varchar(64) comment '物流公司编码', + `invoice_title` varchar(128) comment '发票抬头', + `invoice_type` varchar(64) comment '发票类型', + `buyer_tax_no` varchar(64) comment '发票税号', + `creator_name` varchar(64) comment '业务员', + `plan_delivery_date` datetime comment '计划发货时间', + `node` text comment '线下备注', + `receiver_town` varchar(256) comment '收件信息-街道', + `drp_co_id_to` varchar(256) comment '供销商编号', + `shop_site` varchar(256) comment '店铺站点信息', + `un_lid` varchar(128) comment '国际物流单号', + `end_time` datetime comment '收货时间(仅限头条放心购、京东、拼多多)', + `receiver_country` varchar(32) comment '国家代码', + `receiver_zip` varchar(32) comment '邮编', + `seller_flag` int(11) comment '旗帜(1红旗,2黄旗,3绿旗,4蓝旗,5紫旗))', + `receiver_email` varchar(128) comment '收货邮箱', + `referrer_id` varchar(64) comment '主播id', + `referrer_name` varchar(64) comment '主播名称', + `created` varchar(64) comment '订单创建时间', + `pays` text comment '支付信息', + `items` mediumtext comment '购买商品列表', + `skus` text comment '商品(商品总数.sku_id*qty', + `f_weight` varchar(64) comment '实称重量', + `weight` varchar(64) comment '重量', + `ts` bigint(20) comment '数据库行版本号:https://docs.microsoft.com/zh-cn/sql/t-sql/data-types/rowversion-transact-sql?view=sql-server-ver16', + `buyer_id` varchar(64) comment '买家ID(系统根据shop_buy_id生成的)', + `buyer_paid_amount` varchar(64) comment '买家实付(仅限抖音,拼多多,京东平台订单)', + `seller_income_amount` varchar(64) comment '卖家实收(仅限抖音,拼多多,京东平台订单)', + `chosen_channel` varchar(64) comment '实发快递渠道', + `link_o_id` varchar(64) comment '被合并被拆分的订单内部单号', + `merge_so_id` mediumtext comment '合并订单号', + `shipment` varchar(64) comment '买家指定物流', + `sign_time` varchar(64) comment '预计送达时间', + `cb_finances` varchar(64) comment '跨境线下订单财务数据', + `f_freight` varchar(16) comment '运费成本', + `batch_id` varchar(64) comment '批次号', + `produced_date` varchar(64) comment '生产日期', + `tem_ext_data` varchar(64) comment '订单明细扩展字段', + `discount_rate` varchar(64) comment 'discount_rate', + `tag` text comment 'tag', + `amount` varchar(64) comment 'amount', + `is_split` varchar(64) comment 'is_split', + `is_merge` varchar(64) comment 'is_merge', + `glasses` varchar(64) comment 'glasses', + `outer_as_id` varchar(64) comment 'outer_as_id', + `outer_so_id` varchar(64) comment 'outer_so_id', + `__raw_so_ids__` text comment '__raw_so_ids__', + `ext_datas` text comment 'ext_datas', + `raw_so_id` varchar(64) comment 'raw_so_id', + `drp_from` varchar(64) comment 'drp_from', + `drp_to` varchar(64) comment 'drp_to', + `sync_start_time` datetime comment '同步元信息-修改起始时间', + `sync_end_time` datetime comment '同步元信息-修改结束时间', + `sync_page_index` int(11) comment '同步元信息-页数', + `sync_page_size` int(11) comment '同步元信息-条数', + `creator` varchar(32) comment '创建人', + `create_time` datetime not null default current_timestamp comment '创建时间', + `editor` varchar(32) comment '修改人', + `update_time` datetime not null default current_timestamp on update current_timestamp comment '更新时间', + primary key (`id`), + unique key `uniq_o_id` (`app_key`,`company`,`o_id`) +) engine = innodb comment='聚水潭 订单查询(非淘系订单查询)'; \ No newline at end of file