---初始化项目

This commit is contained in:
2025-09-19 16:14:08 +08:00
parent 902d3d7e3b
commit afee7c03ac
767 changed files with 75809 additions and 82 deletions

View File

@ -0,0 +1,94 @@
package tech.powerjob.remote.framework;
import lombok.Data;
import lombok.experimental.Accessors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import tech.powerjob.common.PowerSerializable;
import tech.powerjob.common.utils.CommonUtils;
import tech.powerjob.remote.framework.actor.Actor;
import tech.powerjob.remote.framework.actor.Handler;
import java.util.Optional;
/**
* 基准测试
*
* @author tjq
* @since 2023/1/1
*/
@Slf4j
@Actor(path = "benchmark")
public class BenchmarkActor {
@Handler(path = "standard")
public BenchmarkResponse standardRequest(BenchmarkRequest request) {
long startTs = System.currentTimeMillis();
log.info("[BenchmarkActor] [standardRequest] receive request: {}", request);
BenchmarkResponse response = new BenchmarkResponse()
.setSuccess(true)
.setContent(request.getContent())
.setProcessThread(Thread.currentThread().getName())
.setServerReceiveTs(System.currentTimeMillis());
if (request.getResponseSize() != null && request.getResponseSize() > 0) {
response.setExtra(RandomStringUtils.randomPrint(request.getResponseSize()));
}
executeSleep(request);
response.setServerCost(System.currentTimeMillis() - startTs);
return response;
}
@Handler(path = "emptyReturn")
public void emptyReturn(BenchmarkRequest request) {
log.info("[BenchmarkActor] [emptyReturn] receive request: {}", request);
executeSleep(request);
}
@Handler(path = "stringReturn")
public String stringReturn(BenchmarkRequest request) {
log.info("[BenchmarkActor] [stringReturn] receive request: {}", request);
executeSleep(request);
return RandomStringUtils.randomPrint(Optional.ofNullable(request.getResponseSize()).orElse(100));
}
private static void executeSleep(BenchmarkRequest request) {
if (request.getBlockingMills() != null && request.getBlockingMills() > 0) {
CommonUtils.easySleep(request.getBlockingMills());
}
}
@Data
@Accessors(chain = true)
public static class BenchmarkRequest implements PowerSerializable {
/**
* 请求内容
*/
private String content;
/**
* 期望的响应大小,可空
*/
private Integer responseSize;
/**
* 阻塞时间,模拟 IO 耗时
*/
private Integer blockingMills;
}
@Data
@Accessors(chain = true)
public static class BenchmarkResponse implements PowerSerializable {
private boolean success;
/**
* 原路返回原来的 content
*/
private String content;
private String processThread;
private long serverReceiveTs;
private long serverCost;
private String extra;
}
}

View File

@ -0,0 +1,21 @@
package tech.powerjob.remote.framework.actor;
import java.lang.annotation.*;
/**
* 行为处理器
*
* @author tjq
* @since 2022/12/31
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Actor {
/**
* root path
* @return root path
*/
String path();
}

View File

@ -0,0 +1,27 @@
package tech.powerjob.remote.framework.actor;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.util.List;
/**
* ActorInfo
*
* @author tjq
* @since 2022/12/31
*/
@Getter
@Setter
@Accessors(chain = true)
public class ActorInfo {
private Object actor;
private Actor anno;
private List<HandlerInfo> handlerInfos;
}

View File

@ -0,0 +1,27 @@
package tech.powerjob.remote.framework.actor;
import java.lang.annotation.*;
/**
* Handler
*
* @author tjq
* @since 2022/12/31
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Handler {
/**
* handler path
* @return handler path
*/
String path();
/**
* 处理类型
* @return 阻塞 or 非阻塞
*/
ProcessType processType() default ProcessType.BLOCKING;
}

View File

@ -0,0 +1,34 @@
package tech.powerjob.remote.framework.actor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import tech.powerjob.remote.framework.base.HandlerLocation;
import java.io.Serializable;
import java.lang.reflect.Method;
/**
* HandlerInfo
*
* @author tjq
* @since 2022/12/31
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class HandlerInfo {
private HandlerLocation location;
/**
* handler 对应的方法
*/
private Method method;
/**
* Handler 注解携带的信息
*/
private Handler anno;
}

View File

@ -0,0 +1,20 @@
package tech.powerjob.remote.framework.actor;
/**
* 处理器类型
*
* @author tjq
* @since 2023/1/1
*/
public enum ProcessType {
/**
* 阻塞式
*/
BLOCKING,
/**
* 非阻塞式
*/
NO_BLOCKING
}

View File

@ -0,0 +1,27 @@
package tech.powerjob.remote.framework.actor;
import lombok.extern.slf4j.Slf4j;
/**
* 内置一个用来通用测试的 TestActor
*
* @author tjq
* @since 2022/12/31
*/
@Slf4j
@Actor(path = "test")
public class TestActor {
public static void simpleStaticMethod() {
}
public void simpleMethod() {
}
@Handler(path = "method1")
public String handlerMethod1() {
log.info("[TestActor] handlerMethod1");
return "1";
}
}

View File

@ -0,0 +1,41 @@
package tech.powerjob.remote.framework.base;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 地址
*
* @author tjq
* @since 2022/12/31
*/
@Getter
@Setter
@Accessors(chain = true)
public class Address implements Serializable {
private String host;
private int port;
public String toFullAddress() {
return toFullAddress(host, port);
}
public static Address fromIpv4(String ipv4) {
String[] split = ipv4.split(":");
return new Address()
.setHost(split[0])
.setPort(Integer.parseInt(split[1]));
}
public static String toFullAddress(String host, int port) {
return String.format("%s:%d", host, port);
}
@Override
public String toString() {
return toFullAddress();
}
}

View File

@ -0,0 +1,33 @@
package tech.powerjob.remote.framework.base;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* handler location
*
* @author tjq
* @since 2022/12/31
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class HandlerLocation implements Serializable {
/**
* 根路径
*/
private String rootPath;
/**
* 方法路径
*/
private String methodPath;
public String toPath() {
return String.format("/%s/%s", rootPath, methodPath);
}
}

View File

@ -0,0 +1,18 @@
package tech.powerjob.remote.framework.base;
/**
* RemotingException
*
* @author tjq
* @since 2022/12/31
*/
public class RemotingException extends RuntimeException {
public RemotingException(String message) {
super(message);
}
public RemotingException(String message, Throwable throwable) {
super(message, throwable);
}
}

View File

@ -0,0 +1,12 @@
package tech.powerjob.remote.framework.base;
/**
* 服务器类型类型
*
* @author tjq
* @since 2022/12/31
*/
public enum ServerType {
SERVER,
WORKER
}

View File

@ -0,0 +1,32 @@
package tech.powerjob.remote.framework.base;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* URL
*
* @author tjq
* @since 2022/12/31
*/
@Data
@Accessors(chain = true)
public class URL implements Serializable {
/**
* 调用的集群类型(用于兼容 AKKA 等除了IP还需要指定 system 访问的情况)
*/
private ServerType serverType;
/**
* remote address
*/
private Address address;
/**
* location
*/
private HandlerLocation location;
}

View File

@ -0,0 +1,43 @@
package tech.powerjob.remote.framework.cs;
import tech.powerjob.remote.framework.actor.ActorInfo;
import tech.powerjob.remote.framework.transporter.Transporter;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
/**
* client & server initializer
*
* @author MuBao
* @since 2022/12/31
*/
public interface CSInitializer {
/**
* 类型名称,比如 akka, netty4httpJson
* @return 名称
*/
String type();
/**
* initialize the framework
* @param config config
*/
void init(CSInitializerConfig config);
/**
* build a Transporter by based network framework
* @return Transporter
*/
Transporter buildTransporter();
/**
* bind Actor, publish handler's service
* @param actorInfos actor infos
*/
void bindHandlers(List<ActorInfo> actorInfos);
void close() throws IOException;
}

View File

@ -0,0 +1,32 @@
package tech.powerjob.remote.framework.cs;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import tech.powerjob.remote.framework.base.Address;
import tech.powerjob.remote.framework.base.ServerType;
import java.io.Serializable;
/**
* CSInitializerConfig
*
* @author tjq
* @since 2022/12/31
*/
@Getter
@Setter
@Accessors(chain = true)
public class CSInitializerConfig implements Serializable {
/**
* 需要绑定的地址(本地)
*/
private Address bindAddress;
/**
* 外部地址(需要 NAT 等情况存在)
*/
private Address externalAddress;
private ServerType serverType;
}

View File

@ -0,0 +1,41 @@
package tech.powerjob.remote.framework.engine;
import lombok.Data;
import lombok.experimental.Accessors;
import tech.powerjob.remote.framework.base.Address;
import tech.powerjob.remote.framework.base.ServerType;
import java.io.Serializable;
import java.util.List;
/**
* EngineConfig
*
* @author tjq
* @since 2022/12/31
*/
@Data
@Accessors(chain = true)
public class EngineConfig implements Serializable {
/**
* 服务类型
*/
private ServerType serverType;
/**
* 需要启动的引擎类型
*/
private String type;
/**
* 绑定的本地地址
*/
private Address bindAddress;
/**
* 外部地址(需要 NAT 等情况存在)
*/
private Address externalAddress;
/**
* actor实例交由使用侧自己实例化以便自行注入各种 bean
*/
private List<Object> actorList;
}

View File

@ -0,0 +1,18 @@
package tech.powerjob.remote.framework.engine;
import lombok.Getter;
import lombok.Setter;
import tech.powerjob.remote.framework.transporter.Transporter;
/**
* 引擎输出
*
* @author tjq
* @since 2022/12/31
*/
@Getter
@Setter
public class EngineOutput {
private Transporter transporter;
}

View File

@ -0,0 +1,16 @@
package tech.powerjob.remote.framework.engine;
import java.io.IOException;
/**
* RemoteEngine
*
* @author tjq
* @since 2022/12/31
*/
public interface RemoteEngine {
EngineOutput start(EngineConfig engineConfig);
void close() throws IOException;
}

View File

@ -0,0 +1,89 @@
package tech.powerjob.remote.framework.engine.impl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import tech.powerjob.remote.framework.actor.Actor;
import tech.powerjob.remote.framework.actor.ActorInfo;
import tech.powerjob.remote.framework.actor.Handler;
import tech.powerjob.remote.framework.actor.HandlerInfo;
import tech.powerjob.remote.framework.base.HandlerLocation;
import java.lang.reflect.Method;
import java.util.List;
/**
* load all Actor
*
* @author tjq
* @since 2022/12/31
*/
@Slf4j
class ActorFactory {
static List<ActorInfo> load(List<Object> actorList) {
List<ActorInfo> actorInfos = Lists.newArrayList();
actorList.forEach(actor -> {
final Class<?> clz = actor.getClass();
try {
final Actor anno = clz.getAnnotation(Actor.class);
ActorInfo actorInfo = new ActorInfo().setActor(actor).setAnno(anno);
actorInfo.setHandlerInfos(loadHandlerInfos4Actor(actorInfo));
actorInfos.add(actorInfo);
} catch (Throwable t) {
log.error("[ActorFactory] process Actor[{}] failed!", clz);
ExceptionUtils.rethrow(t);
}
});
return actorInfos;
}
private static List<HandlerInfo> loadHandlerInfos4Actor(ActorInfo actorInfo) {
List<HandlerInfo> ret = Lists.newArrayList();
Actor anno = actorInfo.getAnno();
String rootPath = anno.path();
Object actor = actorInfo.getActor();
findHandlerMethod(rootPath, actor.getClass(), ret);
return ret;
}
private static void findHandlerMethod(String rootPath, Class<?> clz, List<HandlerInfo> result) {
Method[] declaredMethods = clz.getDeclaredMethods();
for (Method handlerMethod: declaredMethods) {
Handler handlerMethodAnnotation = handlerMethod.getAnnotation(Handler.class);
if (handlerMethodAnnotation == null) {
continue;
}
HandlerLocation handlerLocation = new HandlerLocation()
.setRootPath(suitPath(rootPath))
.setMethodPath(suitPath(handlerMethodAnnotation.path()));
HandlerInfo handlerInfo = new HandlerInfo()
.setAnno(handlerMethodAnnotation)
.setMethod(handlerMethod)
.setLocation(handlerLocation);
result.add(handlerInfo);
}
// 递归处理父类
final Class<?> superclass = clz.getSuperclass();
if (superclass != null) {
findHandlerMethod(rootPath, superclass, result);
}
}
static String suitPath(String path) {
if (path.startsWith("/")) {
return path.replaceFirst("/", "");
}
return path;
}
}

View File

@ -0,0 +1,119 @@
package tech.powerjob.remote.framework.engine.impl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.reflections.Reflections;
import tech.powerjob.common.OmsConstant;
import tech.powerjob.common.enums.Protocol;
import tech.powerjob.common.exception.PowerJobException;
import tech.powerjob.remote.framework.cs.CSInitializer;
import java.util.Optional;
import java.util.Set;
/**
* build CSInitializer
*
* @author tjq
* @since 2022/12/31
*/
@Slf4j
class CSInitializerFactory {
private static final String OFFICIAL_HTTP_CS_INITIALIZER = "tech.powerjob.remote.http.HttpVertxCSInitializer";
/**
* 未来底层框架摆脱 vertx 时可能会用这个 classnameor 开发者自己实现的 http 协议也可以用这个 classname总之预留战未来
*/
private static final String OFFICIAL_HTTP_CS_INITIALIZER2 = "tech.powerjob.remote.http.HttpCSInitializer";
private static final String OFFICIAL_AKKA_CS_INITIALIZER = "tech.powerjob.remote.akka.AkkaCSInitializer";
private static final String OFFICIAL_MU_CS_INITIALIZER = "tech.powerjob.remote.mu.MuCSInitializer";
private static final String EXTEND_CS_INITIALIZER_PATTERN = "tech.powerjob.remote.%s.CSInitializer";
static CSInitializer build(String targetType) {
CSInitializer officialCSInitializer = tryLoadCSInitializerByClassName(targetType);
if (officialCSInitializer != null) {
return officialCSInitializer;
}
log.info("[CSInitializerFactory] try load CSInitializerFactory by name failed, start to use Reflections!");
// JAVA SPI 机制太笨了,短期内继续保留 Reflections 官网下高版本兼容性
Reflections reflections = new Reflections(OmsConstant.PACKAGE);
Set<Class<? extends CSInitializer>> cSInitializerClzSet = reflections.getSubTypesOf(CSInitializer.class);
log.info("[CSInitializerFactory] scan subTypeOf CSInitializer: {}", cSInitializerClzSet);
for (Class<? extends CSInitializer> clz : cSInitializerClzSet) {
try {
CSInitializer csInitializer = clz.getDeclaredConstructor().newInstance();
String type = csInitializer.type();
log.info("[CSInitializerFactory] new instance for CSInitializer[{}] successfully, type={}, object: {}", clz, type, csInitializer);
if (targetType.equalsIgnoreCase(type)) {
return csInitializer;
}
} catch (Exception e) {
log.error("[CSInitializerFactory] new instance for CSInitializer[{}] failed, maybe you should provide a non-parameter constructor", clz);
ExceptionUtils.rethrow(e);
}
}
throw new PowerJobException(String.format("can't load CSInitializer[%s], ensure your package name start with 'tech.powerjob' and import the dependencies!", targetType));
}
/**
* 官方组件直接使用固定类名尝试加载,确保 reflections 不兼容情况下,至少能使用官方通讯协议
* @param targetType 协议类型
* @return CSInitializer
*/
private static CSInitializer tryLoadCSInitializerByClassName(String targetType) {
if (Protocol.HTTP.name().equalsIgnoreCase(targetType)) {
Optional<CSInitializer> httpCsIOpt = tryLoadCSInitializerByClzName(OFFICIAL_HTTP_CS_INITIALIZER);
if (httpCsIOpt.isPresent()) {
return httpCsIOpt.get();
}
Optional<CSInitializer> httpCsIOpt2 = tryLoadCSInitializerByClzName(OFFICIAL_HTTP_CS_INITIALIZER2);
if (httpCsIOpt2.isPresent()) {
return httpCsIOpt2.get();
}
}
if (Protocol.AKKA.name().equalsIgnoreCase(targetType)) {
Optional<CSInitializer> akkaCSIOpt = tryLoadCSInitializerByClzName(OFFICIAL_AKKA_CS_INITIALIZER);
if (akkaCSIOpt.isPresent()) {
return akkaCSIOpt.get();
}
}
if (Protocol.MU.name().equalsIgnoreCase(targetType)) {
Optional<CSInitializer> muCSIOpt = tryLoadCSInitializerByClzName(OFFICIAL_MU_CS_INITIALIZER);
if (muCSIOpt.isPresent()) {
return muCSIOpt.get();
}
}
// 尝试加载按规范命名的处理器,比如使用方自定义了 http2 协议,将其类名定为 tech.powerjob.remote.http2.CSInitializer 依然可确保在 Reflections 不可用的情况下完成加载
String clz = String.format(EXTEND_CS_INITIALIZER_PATTERN, targetType);
Optional<CSInitializer> extOpt = tryLoadCSInitializerByClzName(clz);
return extOpt.orElse(null);
}
private static Optional<CSInitializer> tryLoadCSInitializerByClzName(String clzName) {
try {
log.info("[CSInitializerFactory] try to load CSInitializer by classname: {}", clzName);
Class<?> clz = Class.forName(clzName);
CSInitializer o = (CSInitializer) clz.getDeclaredConstructor().newInstance();
log.info("[CSInitializerFactory] load CSInitializer[{}] successfully, obj: {}", clzName, o);
return Optional.of(o);
} catch (ClassNotFoundException ce) {
log.warn("[CSInitializerFactory] load CSInitializer by classname[{}] failed due to ClassNotFound: {}", clzName, ExceptionUtils.getMessage(ce));
} catch (Exception e) {
log.warn("[CSInitializerFactory] load CSInitializer by classname[{}] failed.", clzName, e);
}
return Optional.empty();
}
}

View File

@ -0,0 +1,79 @@
package tech.powerjob.remote.framework.engine.impl;
import com.google.common.base.Stopwatch;
import lombok.extern.slf4j.Slf4j;
import tech.powerjob.common.utils.SysUtils;
import tech.powerjob.remote.framework.actor.ActorInfo;
import tech.powerjob.remote.framework.actor.TestActor;
import tech.powerjob.remote.framework.cs.CSInitializer;
import tech.powerjob.remote.framework.cs.CSInitializerConfig;
import tech.powerjob.remote.framework.engine.EngineConfig;
import tech.powerjob.remote.framework.engine.EngineOutput;
import tech.powerjob.remote.framework.engine.RemoteEngine;
import tech.powerjob.remote.framework.transporter.Transporter;
import java.io.IOException;
import java.util.List;
/**
* 初始化 PowerJob 整个网络层
*
* @author tjq
* @since 2022/12/31
*/
@Slf4j
public class PowerJobRemoteEngine implements RemoteEngine {
private CSInitializer csInitializer;
@Override
public EngineOutput start(EngineConfig engineConfig) {
reConfig(engineConfig);
final String engineType = engineConfig.getType();
EngineOutput engineOutput = new EngineOutput();
log.info("[PowerJobRemoteEngine] [{}] start remote engine with config: {}", engineType, engineConfig);
List<ActorInfo> actorInfos = ActorFactory.load(engineConfig.getActorList());
csInitializer = CSInitializerFactory.build(engineType);
String type = csInitializer.type();
Stopwatch sw = Stopwatch.createStarted();
log.info("[PowerJobRemoteEngine] [{}] try to startup CSInitializer[type={}]", engineType, type);
csInitializer.init(new CSInitializerConfig()
.setBindAddress(engineConfig.getBindAddress())
.setExternalAddress(engineConfig.getExternalAddress())
.setServerType(engineConfig.getServerType())
);
// 构建通讯器
Transporter transporter = csInitializer.buildTransporter();
engineOutput.setTransporter(transporter);
log.info("[PowerJobRemoteEngine] [{}] start to bind Handler", engineType);
actorInfos.forEach(actor -> actor.getHandlerInfos().forEach(handlerInfo -> log.info("[PowerJobRemoteEngine] [{}] PATH={}, handler={}", engineType, handlerInfo.getLocation().toPath(), handlerInfo.getMethod())));
// 绑定 handler
csInitializer.bindHandlers(actorInfos);
log.info("[PowerJobRemoteEngine] [{}] startup successfully, cost: {}", engineType, sw);
return engineOutput;
}
@Override
public void close() throws IOException {
csInitializer.close();
}
private static void reConfig(EngineConfig engineConfig) {
boolean testEnv = SysUtils.isTestEnv();
if (testEnv) {
log.info("[PowerJobRemoteEngine] add 'TestActor' due to current is test env");
engineConfig.getActorList().add(new TestActor());
}
}
}

View File

@ -0,0 +1,7 @@
/**
* PowerJob 网络框架层
*
* @author tjq
* @since 2022/12/31
*/
package tech.powerjob.remote.framework;

View File

@ -0,0 +1,16 @@
package tech.powerjob.remote.framework.transporter;
/**
* 通讯协议
*
* @author tjq
* @since 2022/12/31
*/
public interface Protocol {
/**
* 通讯协议名称
* @return 协议名称
*/
String name();
}

View File

@ -0,0 +1,40 @@
package tech.powerjob.remote.framework.transporter;
import tech.powerjob.common.PowerSerializable;
import tech.powerjob.remote.framework.base.RemotingException;
import tech.powerjob.remote.framework.base.URL;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutorService;
/**
* 通讯器,封装与远程服务端交互逻辑
*
* @author tjq
* @since 2022/12/31
*/
public interface Transporter {
/**
* Protocol
* @return return protocol
*/
Protocol getProtocol();
/**
*send message
* @param url url
* @param request request
*/
void tell(URL url, PowerSerializable request);
/**
* ask by request
* @param url url
* @param request request
* @param clz response type
* @return CompletionStage
* @throws RemotingException remote exception
*/
<T> CompletionStage<T> ask(URL url, PowerSerializable request, Class<T> clz) throws RemotingException;
}

View File

@ -0,0 +1,35 @@
package tech.powerjob.remote.framework.utils;
import org.apache.commons.lang3.ArrayUtils;
import tech.powerjob.common.PowerSerializable;
import java.util.Optional;
/**
* RemoteUtils
*
* @author tjq
* @since 2023/1/1
*/
public class RemoteUtils {
public static Optional<Class<?>> findPowerSerialize(Class<?>[] parameterTypes) {
if (ArrayUtils.isEmpty(parameterTypes)) {
return Optional.empty();
}
for (Class<?> clz : parameterTypes) {
final Class<?>[] interfaces = clz.getInterfaces();
if (ArrayUtils.isEmpty(interfaces)) {
continue;
}
if (PowerSerializable.class.isAssignableFrom(clz)) {
return Optional.of(clz);
}
}
return Optional.empty();
}
}

View File

@ -0,0 +1,24 @@
package tech.powerjob.remote.framework.base;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
/**
* test address
*
* @author tjq
* @since 2023/1/20
*/
@Slf4j
class AddressTest {
@Test
void testAddress() {
String ip = "192.168.1.1:10085";
final Address address = Address.fromIpv4(ip);
log.info("[AddressTest] parse address: {}", address);
assert ip.equals(address.toFullAddress());
}
}

View File

@ -0,0 +1,28 @@
package tech.powerjob.remote.framework.engine;
import com.google.common.collect.Sets;
import org.junit.jupiter.api.Test;
import tech.powerjob.remote.framework.base.Address;
import tech.powerjob.remote.framework.engine.impl.PowerJobRemoteEngine;
import static org.junit.jupiter.api.Assertions.*;
/**
* RemoteEngineTest
*
* @author tjq
* @since 2022/12/31
*/
class RemoteEngineTest {
@Test
void start() {
RemoteEngine remoteEngine = new PowerJobRemoteEngine();
EngineConfig engineConfig = new EngineConfig();
engineConfig.setType("TEST");
engineConfig.setBindAddress(new Address().setHost("127.0.0.1").setPort(10086));
remoteEngine.start(engineConfig);
}
}

View File

@ -0,0 +1,30 @@
package tech.powerjob.remote.framework.engine.impl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import tech.powerjob.remote.framework.actor.TestActor;
/**
* HandlerFactoryTest
*
* @author tjq
* @since 2022/12/31
*/
@Slf4j
class ActorFactoryTest {
@Test
void load() {
ActorFactory.load(Lists.newArrayList(new TestActor()));
}
@Test
void testSuitPath() {
final String testPath1 = ActorFactory.suitPath("/test");
final String testPath2 = ActorFactory.suitPath("test");
log.info("[ActorFactoryTest] testPath1: {}, testPath2: {}", testPath1, testPath2);
assert testPath1.equals(testPath2);
}
}

View File

@ -0,0 +1,29 @@
package tech.powerjob.remote.framework.engine.impl;
import com.google.common.collect.Sets;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import tech.powerjob.common.exception.PowerJobException;
import static org.junit.jupiter.api.Assertions.*;
/**
* CSInitializerFactoryTest
*
* @author tjq
* @since 2022/12/31
*/
class CSInitializerFactoryTest {
@Test
void testBuildNormal() {
CSInitializerFactory.build("TEST");
}
@Test
void testNotFind() {
Assertions.assertThrows(PowerJobException.class, () -> {
CSInitializerFactory.build("omicron");
});
}
}

View File

@ -0,0 +1,46 @@
package tech.powerjob.remote.framework.test;
import lombok.extern.slf4j.Slf4j;
import tech.powerjob.remote.framework.actor.ActorInfo;
import tech.powerjob.remote.framework.actor.HandlerInfo;
import tech.powerjob.remote.framework.cs.CSInitializer;
import tech.powerjob.remote.framework.cs.CSInitializerConfig;
import tech.powerjob.remote.framework.transporter.Transporter;
import java.io.IOException;
import java.util.List;
/**
* TestCSInitializer
*
* @author tjq
* @since 2022/12/31
*/
@Slf4j
public class TestCSInitializer implements CSInitializer {
@Override
public String type() {
return "TEST";
}
@Override
public void init(CSInitializerConfig config) {
log.info("TestCSInitializer#init");
}
@Override
public Transporter buildTransporter() {
log.info("TestCSInitializer#buildTransporter");
return null;
}
@Override
public void bindHandlers(List<ActorInfo> actorInfos) {
log.info("TestCSInitializer#actorInfos");
}
@Override
public void close() throws IOException {
log.info("TestCSInitializer#close");
}
}

View File

@ -0,0 +1,35 @@
package tech.powerjob.remote.framework.utils;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import tech.powerjob.common.model.AlarmConfig;
import tech.powerjob.common.request.ServerScheduleJobReq;
import java.util.Optional;
/**
* RemoteUtilsTest
*
* @author tjq
* @since 2023/1/1
*/
@Slf4j
class RemoteUtilsTest {
@Test
void findPowerSerialize() {
Class<?>[] contains = {AlarmConfig.class, ServerScheduleJobReq.class};
Class<?>[] notContains = {AlarmConfig.class};
final Optional<Class<?>> notContainsResult = RemoteUtils.findPowerSerialize(notContains);
log.info("[RemoteUtilsTest] notContainsResult: {}", notContainsResult);
final Optional<Class<?>> containsResult = RemoteUtils.findPowerSerialize(contains);
log.info("[RemoteUtilsTest] containsResult: {}", containsResult);
assert !notContainsResult.isPresent();
assert containsResult.isPresent();
}
}