commit 4b772bb3b70054a68221c95085418e0adac15e3e Author: Hanshuo Zeng Date: Wed Mar 4 08:34:08 2020 +0800 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d51e236 --- /dev/null +++ b/.gitignore @@ -0,0 +1,110 @@ +# Created by .ignore support plugin (hsz.mobi) +### Maven template +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +# https://github.com/takari/maven-wrapper#usage-without-binary-jar +.mvn/wrapper/maven-wrapper.jar + +### Java template +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/artifacts +# .idea/compiler.xml +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4dde0c8 --- /dev/null +++ b/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + + com.hans0924 + fsd + 1.0-SNAPSHOT + + + 1.7.30 + 6.0.0 + + + + + org.slf4j + slf4j-log4j12 + ${slf4j.version} + + + org.javolution + javolution-core-java + ${javolution.version} + + + \ No newline at end of file diff --git a/src/main/java/com/hans0924/fsd/Fsd.java b/src/main/java/com/hans0924/fsd/Fsd.java new file mode 100644 index 0000000..c171424 --- /dev/null +++ b/src/main/java/com/hans0924/fsd/Fsd.java @@ -0,0 +1,47 @@ +package com.hans0924.fsd; + +import com.hans0924.fsd.manager.Manage; +import com.hans0924.fsd.process.PMan; +import com.hans0924.fsd.process.config.ConfigManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class Fsd { + private final static Logger LOGGER = LoggerFactory.getLogger(Fsd.class); + + public static ConfigManager configManager; + + + private int clientPort; + + private int serverPort; + + private int systemPort; + + private PMan pManager; + + private String certFile; + + private String whazzupFile; + + private int timer; + private int prevNotify; + private int prevLagCheck; + private int certFileStat; + private int prevCertCheck; + + public Fsd(String configFile) { + LOGGER.info("Booting Server"); + pManager = new PMan(); + + /* Start the information manager */ + Manage.manager = new Manage(); + + configManager = new ConfigManager(configFile); + pManager.registerProcess(configManager); + } +} diff --git a/src/main/java/com/hans0924/fsd/FsdLauncher.java b/src/main/java/com/hans0924/fsd/FsdLauncher.java new file mode 100644 index 0000000..354bc5c --- /dev/null +++ b/src/main/java/com/hans0924/fsd/FsdLauncher.java @@ -0,0 +1,11 @@ +package com.hans0924.fsd; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class FsdLauncher { + public static void main(String[] args) { + + } +} diff --git a/src/main/java/com/hans0924/fsd/constants/ManageVarType.java b/src/main/java/com/hans0924/fsd/constants/ManageVarType.java new file mode 100644 index 0000000..0b00377 --- /dev/null +++ b/src/main/java/com/hans0924/fsd/constants/ManageVarType.java @@ -0,0 +1,13 @@ +package com.hans0924.fsd.constants; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public final class ManageVarType { + public static final int ATT_INT = 1; + + public static final int ATT_VARCHAR = 5; + + public static final int ATT_DATE = 6; +} diff --git a/src/main/java/com/hans0924/fsd/manager/Manage.java b/src/main/java/com/hans0924/fsd/manager/Manage.java new file mode 100644 index 0000000..d0b1b66 --- /dev/null +++ b/src/main/java/com/hans0924/fsd/manager/Manage.java @@ -0,0 +1,111 @@ +package com.hans0924.fsd.manager; + +import com.hans0924.fsd.constants.ManageVarType; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class Manage { + + public static Manage manager; + + private int nVars; + + private List variables; + + public Manage() { + nVars = 0; + variables = new ArrayList(); + } + + public int addVar(String name, int type) { + ManageVar var = new ManageVar(); + var.setType(type); + var.setName(name); + variables.add(var); + return variables.size(); + } + + public void delVar(int num) { + if (variables.size() > num) { + variables.remove(num); + } + } + + public void incVar(int num) { + ManageVar var = variables.get(num); + ManageVarValue value = var.getValue(); + value.setNumber(value.getNumber() + 1); + } + + public void decVar(int num) { + ManageVar var = variables.get(num); + ManageVarValue value = var.getValue(); + value.setNumber(value.getNumber() - 1); + } + + public void setVar(int num, int number) { + ManageVar var = variables.get(num); + ManageVarValue value = var.getValue(); + value.setNumber(number); + } + + public void setVar(int num, String str) { + ManageVar var = variables.get(num); + ManageVarValue value = var.getValue(); + value.setString(str); + } + + public void setVar(int num, long timeVal) { + ManageVar var = variables.get(num); + ManageVarValue value = var.getValue(); + value.setTimeVal(timeVal); + } + + public ManageVarValue getVar(int num) { + if (num >= nVars) { + return null; + } + ManageVar var = variables.get(num); + return var.getValue(); + } + + public int getNVars() { + return nVars; + } + + public String sprintValue(int num) { + if (num >= nVars || variables.get(num).getName() == null) { + return null; + } + ManageVar var = variables.get(num); + + switch (var.getType()) { + case ManageVarType + .ATT_INT: + return String.valueOf(var.getValue().getNumber()); + case ManageVarType.ATT_VARCHAR: + return var.getValue().getString(); + case ManageVarType.ATT_DATE: + return new Date(var.getValue().getTimeVal()).toString(); + } + return ""; + } + + public int getVarNum(String name) { + for (int i = 0; i < variables.size(); i++) { + ManageVar variable = variables.get(i); + if (Objects.equals(variable.getName(), name)) { + return i; + } + } + + return -1; + } +} diff --git a/src/main/java/com/hans0924/fsd/manager/ManageVar.java b/src/main/java/com/hans0924/fsd/manager/ManageVar.java new file mode 100644 index 0000000..79d72ac --- /dev/null +++ b/src/main/java/com/hans0924/fsd/manager/ManageVar.java @@ -0,0 +1,40 @@ +package com.hans0924.fsd.manager; + +import javolution.io.Struct; +import javolution.io.Union; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class ManageVar { + private int type; + + private String name; + + private ManageVarValue value; + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public ManageVarValue getValue() { + return value; + } + + public void setValue(ManageVarValue value) { + this.value = value; + } +} diff --git a/src/main/java/com/hans0924/fsd/manager/ManageVarValue.java b/src/main/java/com/hans0924/fsd/manager/ManageVarValue.java new file mode 100644 index 0000000..737bf4e --- /dev/null +++ b/src/main/java/com/hans0924/fsd/manager/ManageVarValue.java @@ -0,0 +1,37 @@ +package com.hans0924.fsd.manager; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class ManageVarValue { + private int number; + + private String string; + + private long timeVal; + + public int getNumber() { + return number; + } + + public void setNumber(int number) { + this.number = number; + } + + public String getString() { + return string; + } + + public void setString(String string) { + this.string = string; + } + + public long getTimeVal() { + return timeVal; + } + + public void setTimeVal(long timeVal) { + this.timeVal = timeVal; + } +} \ No newline at end of file diff --git a/src/main/java/com/hans0924/fsd/process/PMan.java b/src/main/java/com/hans0924/fsd/process/PMan.java new file mode 100644 index 0000000..4de6aa3 --- /dev/null +++ b/src/main/java/com/hans0924/fsd/process/PMan.java @@ -0,0 +1,42 @@ +package com.hans0924.fsd.process; + +import java.io.IOException; +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; +import java.nio.channels.Selector; +import java.util.Set; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class PMan { + private boolean busy; + + private Selector selector; + + public PMan() throws IOException { + selector = Selector.open(); + busy = false; + } + + public void registerProcess(Process process) throws IOException { + process.getChannel().configureBlocking(false); + SelectionKey selectionKey = process.getChannel().register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE, process); + process.setSelectionKey(selectionKey); + } + + public void run() throws IOException { + long timeOut = busy ? 0 : 1000L; + busy = false; + if (selector.select(timeOut) > 0) { + Set selectionKeys = selector.selectedKeys(); + for (SelectionKey selectionKey : selectionKeys) { + Process attachment = (Process) selectionKey.attachment(); + if (attachment.run()) { + busy = true; + } + } + } + } +} diff --git a/src/main/java/com/hans0924/fsd/process/Process.java b/src/main/java/com/hans0924/fsd/process/Process.java new file mode 100644 index 0000000..b4feccf --- /dev/null +++ b/src/main/java/com/hans0924/fsd/process/Process.java @@ -0,0 +1,40 @@ +package com.hans0924.fsd.process; + +import java.nio.channels.SelectableChannel; +import java.nio.channels.SelectionKey; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public abstract class Process { + + private SelectableChannel channel; + + private SelectionKey selectionKey; + + public Process() { + } + + public int calcMask() { + return 0; + } + + public abstract boolean run(); + + public SelectableChannel getChannel() { + return channel; + } + + public void setChannel(SelectableChannel channel) { + this.channel = channel; + } + + public SelectionKey getSelectionKey() { + return selectionKey; + } + + public void setSelectionKey(SelectionKey selectionKey) { + this.selectionKey = selectionKey; + } +} diff --git a/src/main/java/com/hans0924/fsd/process/config/ConfigEntry.java b/src/main/java/com/hans0924/fsd/process/config/ConfigEntry.java new file mode 100644 index 0000000..1b086d7 --- /dev/null +++ b/src/main/java/com/hans0924/fsd/process/config/ConfigEntry.java @@ -0,0 +1,89 @@ +package com.hans0924.fsd.process.config; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class ConfigEntry { + + private String var; + + private String data; + + private List parts; + + private boolean changed; + + private int nParts; + + public ConfigEntry(String var, String data) { + this.var = var; + this.data = data; + changed = true; + parts = new ArrayList<>(); + } + + public String getData() { + return data; + } + + public void setData(String data) { + this.data = data; + } + + public int getInt() { + return Integer.parseInt(data); + } + + public void fillParts() { + String[] split = data.split(","); + for (String part : split) { + parts.add(part.strip()); + } + nParts = split.length; + } + + public boolean inList(String entry) { + if (parts.isEmpty()) { + fillParts(); + } + for (String part : parts) { + if (Objects.equals(part, entry)) { + return true; + } + } + return false; + } + + public int getNParts() { + if (parts.isEmpty()) { + fillParts(); + } + return nParts; + } + + public String getPart(int num) { + if (parts.isEmpty()) { + fillParts(); + } + if (num >= nParts) { + return null; + } + + return parts.get(num); + } + + public String getVar() { + return var; + } + + public void setVar(String var) { + this.var = var; + } + + +} diff --git a/src/main/java/com/hans0924/fsd/process/config/ConfigGroup.java b/src/main/java/com/hans0924/fsd/process/config/ConfigGroup.java new file mode 100644 index 0000000..9ff8a1c --- /dev/null +++ b/src/main/java/com/hans0924/fsd/process/config/ConfigGroup.java @@ -0,0 +1,71 @@ +package com.hans0924.fsd.process.config; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author 曾韩铄 + * @since 2020-03-04 + */ +public class ConfigGroup { + + private String name; + + private List entries; + + private int nEntries; + + private boolean changed; + + public ConfigGroup(String name) { + this.name = name; + entries = new ArrayList<>(); + nEntries = 0; + changed = true; + } + + public ConfigEntry getEntry(String name) { + for (ConfigEntry entry : entries) { + if (Objects.equals(entry.getVar(), name)) { + return entry; + } + } + + return null; + } + + public ConfigEntry createEntry(String var, String data) { + ConfigEntry configEntry = new ConfigEntry(var, data); + entries.add(configEntry); + return configEntry; + } + + public void handleEntry(String var, String data) { + ConfigEntry entry = getEntry(var); + if (entry == null) { + createEntry(var, data); + changed = true; + return; + } + + if (Objects.equals(entry.getData(), data)) { + return; + } + + entry.setData(data); + changed = true; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public boolean isChanged() { + return changed; + } +} diff --git a/src/main/java/com/hans0924/fsd/process/config/ConfigManager.java b/src/main/java/com/hans0924/fsd/process/config/ConfigManager.java new file mode 100644 index 0000000..75401f4 --- /dev/null +++ b/src/main/java/com/hans0924/fsd/process/config/ConfigManager.java @@ -0,0 +1,138 @@ +package com.hans0924.fsd.process.config; + +import com.hans0924.fsd.constants.ManageVarType; +import com.hans0924.fsd.manager.Manage; +import com.hans0924.fsd.process.Process; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * @author 曾韩铄 + * @since 2020-03-03 + */ +public class ConfigManager extends Process { + private static final Logger LOGGER = LoggerFactory.getLogger(ConfigManager.class); + + private static final long CONFIG_INTERVAL = 10_000L; + private String fileName; + + private List groups; + + private int nGroups; + + private int varAccess; + + private boolean changed; + + private long prevCheck; + + private long lastModify; + + public ConfigManager(String name) { + super(); + fileName = name; + groups = new ArrayList<>(); + nGroups = 0; + changed = true; + int fname = Manage.manager.addVar("config.filename", ManageVarType.ATT_VARCHAR); + Manage.manager.setVar(fname, name); + varAccess = Manage.manager.addVar("config.lastread", ManageVarType.ATT_DATE); + parseFile(); + } + + public ConfigGroup getGroup(String name) { + for (ConfigGroup group : groups) { + if (Objects.equals(group.getName(), name)) { + return group; + } + } + + return null; + } + + public ConfigGroup createGroup(String name) { + ConfigGroup group = new ConfigGroup(name); + groups.add(group); + return group; + } + + @Override + public boolean run() { + long now = System.currentTimeMillis(); + if (now - prevCheck < CONFIG_INTERVAL) { + return false; + } + prevCheck = now; + Path file = Path.of(fileName); + if (Files.notExists(file)) { + return false; + } + try { + BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class); + long fileLastModified = attr.lastModifiedTime().toMillis(); + if (fileLastModified == lastModify) { + return false; + } + lastModify = fileLastModified; + parseFile(); + return true; + } catch (IOException e) { + + return false; + } + } + + public void parseFile() { + File file = new File(fileName); + if (!file.isFile() || !file.exists()) { + return; + } + Manage.manager.setVar(varAccess, System.currentTimeMillis()); + ConfigGroup current = null; + try (InputStreamReader read = new InputStreamReader(new FileInputStream(file)); + BufferedReader bufferedReader = new BufferedReader(read)) { + String line; + + while ((line = bufferedReader.readLine()) != null) + { + if (line.charAt(0) == '#' || line.charAt(0) == '\r' || line.charAt(0) == '\n') { + continue; + } + + if (line.charAt(0) == '[') { + String entry = line.substring(1, line.length() - 1); + current = getGroup(entry); + if (current == null) { + current = createGroup(entry); + } + continue; + } + + if (current == null) { + continue; + } + + String[] split = line.split("="); + if (split.length > 1) { + current.handleEntry(split[0], split[1]); + } + if (current.isChanged()) { + changed = true; + } + } + } catch (FileNotFoundException e) { + LOGGER.error("Config file not found: " + fileName); + } catch (IOException e) { + LOGGER.error("Something went wrong when parse config file: ", e); + } + prevCheck = System.currentTimeMillis(); + } +} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties new file mode 100644 index 0000000..d5a370e --- /dev/null +++ b/src/main/resources/log4j.properties @@ -0,0 +1,39 @@ +#日志级别大小: DEBUG < INFO < WARN < ERROR < FATAL +#log4j.rootLogger 配置的是大于等于当前级别的日志信息的输出 +#log4j.rootLogger 用法:(注意appenderName可以是一个或多个) +#log4j.rootLogger = 日志级别,appenderName1,appenderName2,.... +#log4j.appender.appenderName1定义的是日志的输出方式,有两种:一种是命令行输出或者叫控制台输出,另一种是文件方式保存 +# 1)控制台输出则应该配置为org.apache.log4j.PatternLayout +# 2)文本方式保存应该配置为org.apache.log4j.DailyRollingFileAppender +# 3)也可以自定义 Appender类 +#log4j.appender.appenderName1.layout.ConversionPattern 定义的是日志内容格式 +#log4j.appender.appenderName1.file 定义了该日志文件的文件名称 +#log4j.appender.appenderName1.DatePattern 定义了日志文件重新生成的时间间隔,如果设置到天,则每天重新生成一个新的日志文件。 +# 旧的日志文件则以新的文件名保存,文件名称 = log4j.appender.appenderName1.file + log4j.appender.appenderName1.DatePattern +#log4j.rootLogger = info,stdout,file +log4j.rootLogger = info,stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%C{1}:%L] - %m%n +#log4j.appender.file = org.apache.log4j.DailyRollingFileAppender +#log4j.appender.file.file=d\:\\log\\info(+).log +#log4j.appender.file.DatePattern= '.'yyyy-MM-dd +#log4j.appender.file.layout=org.apache.log4j.PatternLayout +#log4j.appender.file.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%C{1}:%L] - %m%n + + +# log4j.logger 用法如下 +# 1)log4j.logger.包名 = 日志级别 , appenderName1,appenderName2,.... +# 定义该包名下的所有类的日志输出 +# 2)log4j.logger.类全名含包名 = 日志级别 , appenderName1,appenderName2,.... +# 定义指定类的日志输出 +# 3) log4j.logger.日志对象Logger命名名称 = 日志级别 , appenderName1,appenderName2,.... +# 定义了某命名名称的日志的 输出,如: +# log4j.logger.Log1 就是指定义通过 Logger.getLogger("Log1") 获取的日志对象的日志输出 + +log4j.logger.edu.mvcdemo.controller = debug,controller_logfile +log4j.appender.controller_logfile = org.apache.log4j.DailyRollingFileAppender +log4j.appender.controller_logfile.file= fsd.log +log4j.appender.controller_logfile.DatePattern= '.'yyyy-MM-dd +log4j.appender.controller_logfile.layout=org.apache.log4j.PatternLayout +log4j.appender.controller_logfile.layout.ConversionPattern=[%p][%d{yyyy-MM-dd HH:mm:ss}][%C{1}:%L] - %m%n \ No newline at end of file