change: 日常小调整.

This commit is contained in:
2024-06-30 09:46:34 +08:00
parent 850b5b80ad
commit e76fd2915a
16 changed files with 103 additions and 49 deletions

View File

@@ -18,13 +18,13 @@ public final class ManagerLite {
init();
}
private static SystemInitializer init() {
private static void init() {
SystemInitializer systemInitializer = SystemInitializer
.configurer()
.clearCache(false)
.configuration(new PropertiesConfiguration(SystemConstants.USER_SETTINGS_PROPERTIES_PATH))
.instanceContext(new FileInstanceContext())
.done();
systemInitializer.refresh();
return systemInitializer;
}
}

View File

@@ -1,8 +1,8 @@
package com.serliunx.ddns.support.feign.client;
package com.serliunx.ddns.client;
import com.serliunx.ddns.client.entity.IPAddressResponse;
import com.serliunx.ddns.support.feign.JacksonDecoder;
import com.serliunx.ddns.support.feign.JacksonEncoder;
import com.serliunx.ddns.support.feign.client.entity.IPAddressResponse;
import feign.Feign;
import feign.Logger;
import feign.RequestLine;
@@ -27,7 +27,7 @@ public interface IPAddressClient {
* @return IPAddressResponse
*/
@RequestLine("GET /json")
IPAddressResponse getIPAddress();
IPAddressResponse getIPAddress();
static IPAddressClient getInstance() {
return Feign.builder()

View File

@@ -1,4 +1,4 @@
package com.serliunx.ddns.support.feign.client.entity;
package com.serliunx.ddns.client.entity;
/**
* IP地址查询响应

View File

@@ -14,15 +14,15 @@ import java.util.Map;
* @since 2024/5/15
*/
public final class InstanceClasses {
private InstanceClasses(){throw new UnsupportedOperationException();}
private static final Map<InstanceType, Class<? extends Instance>> instanceTypeMap =
new HashMap<InstanceType, Class<? extends Instance>>() {
{
put(InstanceType.ALI_YUN, AliyunInstance.class);
put(InstanceType.TENCENT_CLOUD, TencentInstance.class);
}
};
private static final Map<InstanceType, Class<? extends Instance>> instanceTypeMap = new HashMap<>();
static {
instanceTypeMap.put(InstanceType.ALI_YUN, AliyunInstance.class);
instanceTypeMap.put(InstanceType.TENCENT_CLOUD, TencentInstance.class);
}
public static Class<? extends Instance> match(InstanceType type) {
return instanceTypeMap.get(type);

View File

@@ -25,7 +25,7 @@ import static com.serliunx.ddns.util.InstanceUtils.validateInstance;
*/
public abstract class AbstractInstanceContext implements InstanceContext, MultipleSourceInstanceContext {
private static final Logger log = LoggerFactory.getLogger(AbstractInstanceContext.class);
private final Logger log = LoggerFactory.getLogger(this.getClass());
private final Set<ListableInstanceFactory> listableInstanceFactories = new HashSet<>();
@@ -63,9 +63,7 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip
Set<Instance> instances = new HashSet<>();
// 高优先级的实例工厂会覆盖低优先级实例工厂所加载的实例
listableInstanceFactories.stream()
.sorted()
.forEach(f -> instances.addAll(f.getInstances()));
getSortedListableInstanceFactories().forEach(f -> instances.addAll(f.getInstances()));
// 初次载入
cacheInstanceMap = new HashMap<>(instances.stream().collect(Collectors.toMap(Instance::getName, i -> i)));
@@ -86,10 +84,11 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip
instanceLock.lock();
String name = instance.getName();
Instance instanceExists = instanceMap.get(name);
if (instanceExists != null)
if (instanceExists != null) {
throw new InstanceExistsException("该实例已存在!", name, instanceExists);
else
} else {
instanceMap.put(name, instance);
}
}catch (Exception e){
throw new RuntimeException(e);
}finally {
@@ -146,7 +145,7 @@ public abstract class AbstractInstanceContext implements InstanceContext, Multip
protected void clearCache() {
if (cacheInstanceMap != null
&& !cacheInstanceMap.isEmpty()){
int size = cacheInstanceMap.size();
final int size = cacheInstanceMap.size();
cacheInstanceMap.clear();
// 清理实例工厂的缓存信息
listableInstanceFactories.forEach(Clearable::clear);

View File

@@ -3,7 +3,10 @@ package com.serliunx.ddns.core.context;
import com.serliunx.ddns.core.factory.InstanceFactory;
import com.serliunx.ddns.core.factory.ListableInstanceFactory;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 多数据源的实例容器, 将多种实例来源汇聚到一起
@@ -26,4 +29,18 @@ public interface MultipleSourceInstanceContext extends InstanceContext, Listable
* @return 实例工厂列表
*/
Set<ListableInstanceFactory> getListableInstanceFactories();
/**
* 获取当前实例容器下所有实例工厂(已排序)
* @return 已排序的实例工厂
*/
default List<ListableInstanceFactory> getSortedListableInstanceFactories() {
Set<ListableInstanceFactory> listableInstanceFactories = getListableInstanceFactories();
if (listableInstanceFactories == null || listableInstanceFactories.isEmpty())
return Collections.emptyList();
return listableInstanceFactories.stream()
.sorted()
.collect(Collectors.toList());
}
}

View File

@@ -74,6 +74,11 @@ public abstract class AbstractInstanceFactory implements InstanceFactory, Listab
clear0();
}
@Override
public String toString() {
return getClass().getSimpleName() + "(priority: " + getPriority() + ")";
}
/**
* 交由子类去加载实例信息
* @return 实例信息

View File

@@ -26,6 +26,16 @@ public abstract class FileInstanceFactory extends AbstractInstanceFactory {
this.instanceDir = instanceDir;
}
@Override
public int getPriority() {
return 256;
}
@Override
public String toString() {
return getClass().getSimpleName() + "(instanceDir: " + instanceDir + ", priority: " + getPriority() + ")";
}
@Override
protected Set<Instance> load() {
Set<File> files = loadFiles();
@@ -38,11 +48,6 @@ public abstract class FileInstanceFactory extends AbstractInstanceFactory {
return Collections.emptySet();
}
@Override
public int getPriority() {
return 256;
}
/**
* 交由具体的子类去加载实例, 比如: json格式的实例信息、xml格式的实例信息
* @param file 文件信息

View File

@@ -96,12 +96,14 @@ public class YamlFileInstanceFactory extends FileInstanceFactory {
f.set(instance, Enum.valueOf((Class<? extends Enum>) clazz, (String) value));
continue;
}
if (value != null)
if (value != null) {
f.set(instance, value);
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} finally {
f.setAccessible(false);
}
f.setAccessible(false);
}
return instance;
}

View File

@@ -23,7 +23,7 @@ import static com.serliunx.ddns.constant.SystemConstants.XML_ROOT_INSTANCE_NAME;
@JacksonXmlRootElement(localName = XML_ROOT_INSTANCE_NAME)
public abstract class AbstractInstance implements Instance {
private static final Logger log = LoggerFactory.getLogger(AbstractInstance.class);
private final Logger log = LoggerFactory.getLogger(this.getClass());
/**
* 实例名称

View File

@@ -14,6 +14,7 @@ public final class Configurer {
private Configuration configuration;
private MultipleSourceInstanceContext instanceContext;
private boolean clearCache;
Configurer(){}
@@ -29,8 +30,13 @@ public final class Configurer {
return this;
}
public Configurer clearCache(boolean clearCache) {
this.clearCache = clearCache;
return this;
}
public SystemInitializer done() {
Assert.notNull(configuration, instanceContext);
return new SystemInitializer(configuration, instanceContext);
return new SystemInitializer(configuration, instanceContext, clearCache);
}
}

View File

@@ -39,8 +39,9 @@ public final class NetworkContextHolder {
}
public static String getIpAddress() {
if(IP_ADDRESS != null)
if(IP_ADDRESS != null) {
return IP_ADDRESS;
}
try {
if(!IP_CONTEXT_WAIT_LATCH.await(IP_CONTEXT_TIME_OUT, TimeUnit.SECONDS)) {
log.error("IP地址获取超时.");

View File

@@ -6,8 +6,8 @@ import com.serliunx.ddns.core.Clearable;
import com.serliunx.ddns.core.Refreshable;
import com.serliunx.ddns.core.context.MultipleSourceInstanceContext;
import com.serliunx.ddns.core.instance.Instance;
import com.serliunx.ddns.support.feign.client.IPAddressClient;
import com.serliunx.ddns.support.feign.client.entity.IPAddressResponse;
import com.serliunx.ddns.client.IPAddressClient;
import com.serliunx.ddns.client.entity.IPAddressResponse;
import com.serliunx.ddns.thread.TaskThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,14 +40,20 @@ public final class SystemInitializer implements Refreshable, Clearable {
private final Configuration configuration;
private final MultipleSourceInstanceContext instanceContext;
private final boolean clearCache;
private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
private Set<Instance> instances;
private final Map<String, ScheduledFuture<?>> runningInstances = new HashMap<>(64);
SystemInitializer(Configuration configuration, MultipleSourceInstanceContext instanceContext) {
SystemInitializer(Configuration configuration, MultipleSourceInstanceContext instanceContext, boolean clearCache) {
this.configuration = configuration;
this.instanceContext = instanceContext;
this.clearCache = clearCache;
}
SystemInitializer(Configuration configuration, MultipleSourceInstanceContext instanceContext) {
this(configuration, instanceContext, true);
}
public static Configurer configurer() {
@@ -80,8 +86,10 @@ public final class SystemInitializer implements Refreshable, Clearable {
// 运行实例
runInstances();
// 实例提交后, 清理实例、配置缓存, 因为读取一次就不需要了
clear();
// 清理实例、配置缓存, 正常情况下读取一次就不需要了
if (clearCache) {
clear();
}
log.info("初始化完成!");
InstanceContextHolder.clearAdditional();
}
@@ -120,8 +128,9 @@ public final class SystemInitializer implements Refreshable, Clearable {
byte[] buffer = new byte[1024];
int bytesRead;
if (inputStream != null) {
while ((bytesRead = inputStream.read(buffer)) != -1)
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
}
outputStream.close();
} catch (Exception e) {
@@ -140,7 +149,7 @@ public final class SystemInitializer implements Refreshable, Clearable {
}
// 初始化实例
i.refresh();
ScheduledFuture<?> future = scheduledThreadPoolExecutor.scheduleWithFixedDelay(i, 0,
ScheduledFuture<?> future = scheduledThreadPoolExecutor.scheduleWithFixedDelay(i, 5,
i.getInterval(), TimeUnit.SECONDS);
runningInstances.put(i.getName(), future);
log.info("{}({})已启动, 运行周期 {} 秒.", i.getName(), i.getType(), i.getInterval());
@@ -187,15 +196,15 @@ public final class SystemInitializer implements Refreshable, Clearable {
boolean result = scheduledThreadPoolExecutor.awaitTermination(5, TimeUnit.SECONDS);
if (result) {
log.error("线程池无法在正常的时间范围内关闭, 将强制关闭线程池!");
if (!scheduledThreadPoolExecutor.isShutdown())
if (!scheduledThreadPoolExecutor.isShutdown()) {
scheduledThreadPoolExecutor.shutdownNow();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
instances.clear();
runningInstances.clear();
} finally {
instances.clear();
runningInstances.clear();
}
}
}

View File

@@ -34,9 +34,8 @@ public class ContextTest {
@Test
public void testFileContext(){
MultipleSourceInstanceContext context = new FileInstanceContext();
context.getInstances().forEach(System.out::println);
FileInstanceContext context = new FileInstanceContext();
context.getSortedListableInstanceFactories().forEach(System.out::println);
}
@Test

View File

@@ -1,9 +1,15 @@
package com.serliunx.ddns.test;
import com.serliunx.ddns.constant.InstanceType;
import com.serliunx.ddns.constant.SystemConstants;
import com.serliunx.ddns.core.factory.InstanceFactory;
import com.serliunx.ddns.core.factory.ListableInstanceFactory;
import com.serliunx.ddns.core.factory.YamlFileInstanceFactory;
import com.serliunx.ddns.core.instance.Instance;
import org.junit.Test;
import java.util.Map;
/**
* @author SerLiunx
* @since 1.0
@@ -12,9 +18,14 @@ public class FactoryTest {
@Test
public void testYamlFileFactory() {
YamlFileInstanceFactory factory = new YamlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR);
ListableInstanceFactory factory = new YamlFileInstanceFactory(SystemConstants.USER_INSTANCE_DIR);
factory.refresh();
factory.getInstances().forEach(System.out::println);
factory.clear();
Map<String, Instance> instances = factory.getInstanceOfType(InstanceType.TENCENT_CLOUD);
instances.forEach((k, v) -> {
System.out.println(k + ": " + v);
});
}
}

View File

@@ -1,6 +1,6 @@
package com.serliunx.ddns.test.support;
import com.serliunx.ddns.support.feign.client.IPAddressClient;
import com.serliunx.ddns.client.IPAddressClient;
import org.junit.Test;
/**