Compare commits
No commits in common. "main" and "verze3" have entirely different histories.
|
|
@ -1 +0,0 @@
|
|||
*.log
|
||||
73
build.xml
73
build.xml
|
|
@ -1,73 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- You may freely edit this file. See commented blocks below for -->
|
||||
<!-- some examples of how to customize the build. -->
|
||||
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||
<!-- the Compile on Save feature is turned off for the project. -->
|
||||
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||
<!-- in the project's Project Properties dialog box.-->
|
||||
<project name="jNetServer" default="default" basedir=".">
|
||||
<description>Builds, tests, and runs the project jNetServer.</description>
|
||||
<import file="nbproject/build-impl.xml"/>
|
||||
<!--
|
||||
|
||||
There exist several targets which are by default empty and which can be
|
||||
used for execution of your tasks. These targets are usually executed
|
||||
before and after some main targets. They are:
|
||||
|
||||
-pre-init: called before initialization of project properties
|
||||
-post-init: called after initialization of project properties
|
||||
-pre-compile: called before javac compilation
|
||||
-post-compile: called after javac compilation
|
||||
-pre-compile-single: called before javac compilation of single file
|
||||
-post-compile-single: called after javac compilation of single file
|
||||
-pre-compile-test: called before javac compilation of JUnit tests
|
||||
-post-compile-test: called after javac compilation of JUnit tests
|
||||
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||
-pre-jar: called before JAR building
|
||||
-post-jar: called after JAR building
|
||||
-post-clean: called after cleaning build products
|
||||
|
||||
(Targets beginning with '-' are not intended to be called on their own.)
|
||||
|
||||
Example of inserting an obfuscator after compilation could look like this:
|
||||
|
||||
<target name="-post-compile">
|
||||
<obfuscate>
|
||||
<fileset dir="${build.classes.dir}"/>
|
||||
</obfuscate>
|
||||
</target>
|
||||
|
||||
For list of available properties check the imported
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
|
||||
Another way to customize the build is by overriding existing main targets.
|
||||
The targets of interest are:
|
||||
|
||||
-init-macrodef-javac: defines macro for javac compilation
|
||||
-init-macrodef-junit: defines macro for junit execution
|
||||
-init-macrodef-debug: defines macro for class debugging
|
||||
-init-macrodef-java: defines macro for class execution
|
||||
-do-jar: JAR building
|
||||
run: execution of project
|
||||
-javadoc-build: Javadoc generation
|
||||
test-report: JUnit report generation
|
||||
|
||||
An example of overriding the target for project execution could look like this:
|
||||
|
||||
<target name="run" depends="jNetServer-impl.jar">
|
||||
<exec dir="bin" executable="launcher.exe">
|
||||
<arg file="${dist.jar}"/>
|
||||
</exec>
|
||||
</target>
|
||||
|
||||
Notice that the overridden target depends on the jar target and not only on
|
||||
the compile target as the regular run target does. Again, for a list of available
|
||||
properties which you can use, check the target you are overriding in the
|
||||
nbproject/build-impl.xml file.
|
||||
|
||||
-->
|
||||
</project>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>jnet</groupId>
|
||||
<artifactId>jNetServer</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<build>
|
||||
<finalName>jNetServer</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<shadedClassifierName>null</shadedClassifierName>
|
||||
<transformers>
|
||||
<transformer />
|
||||
<transformer>
|
||||
<mainClass>jnet.server.Server</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<filters>
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
<filter>
|
||||
<artifact>jnet:jNetServer</artifact>
|
||||
<excludes>
|
||||
<exclude>db/**</exclude>
|
||||
<exclude>assets/**</exclude>
|
||||
<exclude>**/*.properties</exclude>
|
||||
<exclude>**/*.dtd</exclude>
|
||||
<exclude>**/*.md</exclude>
|
||||
<exclude>**/*.service</exclude>
|
||||
<exclude>**/LICENSE</exclude>
|
||||
<exclude>**/README</exclude>
|
||||
<exclude>**/navod</exclude>
|
||||
<exclude>**/INFO_BIN</exclude>
|
||||
<exclude>**/INFO_SRC</exclude>
|
||||
<exclude>**/CONTRIBUTING.md</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<release>${maven.compiler.release}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<properties>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<exec.mainClass>jnet.server.Server</exec.mainClass>
|
||||
</properties>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
27.08.26 18:45:51 I ---------------------------------------------
|
||||
27.08.26 18:45:51 I jNet Server
|
||||
27.08.26 18:45:51 I Version: 3 (Thu Aug 27 16:59:16 CEST 2026)
|
||||
27.08.26 18:45:51 I ---------------------------------------------
|
||||
27.08.26 18:45:51 I
|
||||
27.08.26 18:45:51 I Loading config ...
|
||||
27.08.26 18:45:52 I successfully
|
||||
27.08.26 18:45:52 D Debug mode on
|
||||
27.08.26 18:45:52 I Ugrade database ...
|
||||
27.08.26 18:45:52 I Number of migrations performed: 0
|
||||
27.08.26 18:45:52 I Connecting to database ...
|
||||
27.08.26 18:45:53 I successfully
|
||||
27.08.26 18:45:53 I Loading user list ...
|
||||
27.08.26 18:45:53 I load 4 user(s)
|
||||
27.08.26 18:45:53 I Loading node icon ...
|
||||
27.08.26 18:45:53 I load 10 icon(s)
|
||||
27.08.26 18:45:53 I Loading map and object list ...
|
||||
27.08.26 18:45:53 I load 8 maps
|
||||
27.08.26 18:45:53 I Loading events list ...
|
||||
27.08.26 18:45:53 I load 436 events
|
||||
27.08.26 18:45:53 I Loading SNMP profile list ...
|
||||
27.08.26 18:45:53 I load 5 profile(s)
|
||||
27.08.26 18:45:53 I Loading SNMP template list ...
|
||||
27.08.26 18:45:53 I load 4 templates(s)
|
||||
27.08.26 18:45:53 I Loading SNMP template value map list ...
|
||||
27.08.26 18:45:53 I load 1 value map(s)
|
||||
27.08.26 18:45:53 I Spoustim SNMP monitor (dotaz=5000ms, davka=2000ms)
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=3
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=5
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=6
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=7
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=8
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=9
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=10
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=11
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=12
|
||||
27.08.26 18:45:53 I SNMP zarizeni pridano: ID=14
|
||||
27.08.26 18:45:53 I Nacteno 10 monitoru, preskoceno 2
|
||||
27.08.26 18:45:53 I Monitor spusten, interval=5000ms, zarizeni=10
|
||||
27.08.26 18:45:53 I TrafficBatchDispatcher spusten, interval=2000ms
|
||||
27.08.26 18:45:53 I SNMP monitor spusten, zarizeni=10
|
||||
27.08.26 18:45:58 I Ping probe starting...
|
||||
27.08.26 18:45:58 I Loaded 16 targets.
|
||||
27.08.26 18:45:58 I OS is Windows - using PingEngine (subprocess ping)
|
||||
27.08.26 18:45:58 I Targets set.
|
||||
27.08.26 18:45:58 I Starting engine...
|
||||
27.08.26 18:45:58 I Engine started successfully.
|
||||
27.08.26 18:46:00 I Starting Netty on port 1225
|
||||
27.08.26 18:46:01 I New client: /127.0.0.1:56938
|
||||
27.08.26 18:46:01 D Received message ID: 501
|
||||
27.08.26 18:46:01 D Received message ID: 502
|
||||
27.08.26 18:46:02 I User: michal logged in (127.0.0.1)
|
||||
27.08.26 18:47:40 D CHANGE: Node 25 (10.10.0.39) -> DOWN
|
||||
27.08.26 18:47:48 D CHANGE: Node 25 (10.10.0.39) -> UP, odezva 2 ms
|
||||
27.08.26 19:23:20 D CHANGE: Node 27 (10.10.0.254) -> DOWN
|
||||
27.08.26 19:23:28 D CHANGE: Node 27 (10.10.0.254) -> UP, odezva 3 ms
|
||||
27.08.26 20:12:00 D CHANGE: Node 27 (10.10.0.254) -> DOWN
|
||||
27.08.26 20:12:08 D CHANGE: Node 27 (10.10.0.254) -> UP, odezva 2 ms
|
||||
27.08.26 20:13:50 D CHANGE: Node 25 (10.10.0.39) -> DOWN
|
||||
27.08.26 20:13:58 D CHANGE: Node 25 (10.10.0.39) -> UP, odezva 3 ms
|
||||
27.08.26 21:3:40 D CHANGE: Node 27 (10.10.0.254) -> DOWN
|
||||
27.08.26 21:3:48 D CHANGE: Node 27 (10.10.0.254) -> UP, odezva 2 ms
|
||||
27.08.26 21:25:00 D CHANGE: Node 29 (10.0.0.219) -> DOWN
|
||||
27.08.26 21:25:08 D CHANGE: Node 29 (10.0.0.219) -> UP, odezva 4 ms
|
||||
27.08.26 21:27:30 D CHANGE: Node 4 (10.0.0.220) -> DOWN
|
||||
27.08.26 21:27:38 D CHANGE: Node 4 (10.0.0.220) -> UP, odezva 5 ms
|
||||
27.08.26 21:42:00 D CHANGE: Node 27 (10.10.0.254) -> DOWN
|
||||
27.08.26 21:42:08 D CHANGE: Node 27 (10.10.0.254) -> UP, odezva 4 ms
|
||||
27.08.26 21:58:00 D CHANGE: Node 25 (10.10.0.39) -> DOWN
|
||||
27.08.26 21:58:08 D CHANGE: Node 25 (10.10.0.39) -> UP, odezva 2 ms
|
||||
27.08.26 21:59:20 D CHANGE: Node 4 (10.0.0.220) -> DOWN
|
||||
27.08.26 21:59:28 D CHANGE: Node 4 (10.0.0.220) -> UP, odezva 6 ms
|
||||
60
log.log
60
log.log
|
|
@ -1,60 +0,0 @@
|
|||
13.02.25 18:7:16 I ---------------------------------------------
|
||||
13.02.25 18:7:16 I jNet Server
|
||||
13.02.25 18:7:16 I Version: 1 (Thu Feb 13 09:04:35 CET 2025)
|
||||
13.02.25 18:7:16 I ---------------------------------------------
|
||||
13.02.25 18:7:16 I
|
||||
13.02.25 18:7:16 I Loading config ...
|
||||
13.02.25 18:7:16 I successfully
|
||||
13.02.25 18:7:16 D Debug mode on
|
||||
13.02.25 18:7:16 I Connecting to a selected database ...
|
||||
13.02.25 18:7:16 I successfully
|
||||
13.02.25 18:7:16 I Loading user list ...
|
||||
13.02.25 18:7:16 I load 2 user(s)
|
||||
13.02.25 18:7:16 I Loading map list ...
|
||||
13.02.25 18:7:16 I load 6 map(s)
|
||||
13.02.25 18:7:16 I Loading object list ...
|
||||
13.02.25 18:7:17 I load 8 object(s)
|
||||
13.02.25 18:7:17 I Loading object type ...
|
||||
13.02.25 18:7:17 I load 12 type(s)
|
||||
13.02.25 18:7:17 I Loading SNMP profile ...
|
||||
13.02.25 18:7:17 I load 2 profile(s)
|
||||
13.02.25 18:7:17 I Loading events ...
|
||||
13.02.25 18:7:17 I load 30 event(s)
|
||||
13.02.25 18:7:17 I Ping probe start
|
||||
13.02.25 18:7:17 I Server is ready and listening on port 1225
|
||||
13.02.25 18:7:49 D -> Message type: 1
|
||||
13.02.25 18:7:49 I Authorization request send (kubernetes.docker.internal)
|
||||
13.02.25 18:7:49 D <- Message type: 3
|
||||
13.02.25 18:7:49 D -> Message type: 4
|
||||
13.02.25 18:7:49 I User: michal logged in (kubernetes.docker.internal)
|
||||
13.02.25 18:7:49 D <- Message type: 5
|
||||
13.02.25 18:7:49 D <- Message type: 9
|
||||
13.02.25 18:7:49 D <- For all. Message type: 7
|
||||
13.02.25 18:7:49 D <- Message type: 13
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 8
|
||||
13.02.25 18:7:49 D <- Message type: 11
|
||||
13.02.25 18:7:49 D <- Message type: 11
|
||||
13.02.25 18:7:49 D <- Message type: 100
|
||||
13.02.25 18:7:49 D <- Message type: 100
|
||||
13.02.25 18:7:49 D <- Message type: 100
|
||||
13.02.25 18:7:49 D <- Message type: 100
|
||||
13.02.25 18:7:49 D <- Message type: 100
|
||||
13.02.25 18:7:49 D <- Message type: 100
|
||||
13.02.25 18:7:49 D <- Message type: 14
|
||||
13.02.25 18:7:49 D <- Message type: 110
|
||||
13.02.25 18:7:49 D <- Message type: 107
|
||||
13.02.25 18:7:49 D <- Message type: 107
|
||||
13.02.25 18:8:31 D -> Message type: 105
|
||||
13.02.25 18:8:31 D <- For all. Message type: 105
|
||||
13.02.25 18:8:31 D <- For all. Message type: 108
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Manifest-Version: 1.0
|
||||
X-COMMENT: Main-Class will be added automatically by build
|
||||
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actions>
|
||||
<action>
|
||||
<actionName>run</actionName>
|
||||
<packagings>
|
||||
<packaging>jar</packaging>
|
||||
</packagings>
|
||||
<goals>
|
||||
<goal>process-classes</goal>
|
||||
<goal>org.codehaus.mojo:exec-maven-plugin:3.5.1:exec</goal>
|
||||
</goals>
|
||||
<properties>
|
||||
<exec.vmArgs>-Dio.netty.noUnsafe=true -Dio.netty.tryUnsafe=false</exec.vmArgs>
|
||||
<exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args>
|
||||
<exec.appArgs></exec.appArgs>
|
||||
<exec.mainClass>${packageClassName}</exec.mainClass>
|
||||
<exec.executable>java</exec.executable>
|
||||
</properties>
|
||||
</action>
|
||||
<action>
|
||||
<actionName>debug</actionName>
|
||||
<packagings>
|
||||
<packaging>jar</packaging>
|
||||
</packagings>
|
||||
<goals>
|
||||
<goal>process-classes</goal>
|
||||
<goal>org.codehaus.mojo:exec-maven-plugin:3.5.1:exec</goal>
|
||||
</goals>
|
||||
<properties>
|
||||
<exec.vmArgs>-Dio.netty.noUnsafe=true -Dio.netty.tryUnsafe=false -agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</exec.vmArgs>
|
||||
<exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args>
|
||||
<exec.appArgs></exec.appArgs>
|
||||
<exec.mainClass>${packageClassName}</exec.mainClass>
|
||||
<exec.executable>java</exec.executable>
|
||||
<jpda.listen>true</jpda.listen>
|
||||
</properties>
|
||||
</action>
|
||||
<action>
|
||||
<actionName>profile</actionName>
|
||||
<packagings>
|
||||
<packaging>jar</packaging>
|
||||
</packagings>
|
||||
<goals>
|
||||
<goal>process-classes</goal>
|
||||
<goal>org.codehaus.mojo:exec-maven-plugin:3.5.1:exec</goal>
|
||||
</goals>
|
||||
<properties>
|
||||
<exec.vmArgs>-Dio.netty.noUnsafe=true -Dio.netty.tryUnsafe=false</exec.vmArgs>
|
||||
<exec.args>${exec.vmArgs} -classpath %classpath ${exec.mainClass} ${exec.appArgs}</exec.args>
|
||||
<exec.mainClass>${packageClassName}</exec.mainClass>
|
||||
<exec.executable>java</exec.executable>
|
||||
<exec.appArgs></exec.appArgs>
|
||||
</properties>
|
||||
</action>
|
||||
</actions>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +0,0 @@
|
|||
build.xml.data.CRC32=36922983
|
||||
build.xml.script.CRC32=49bb365f
|
||||
build.xml.stylesheet.CRC32=f85dc8f2@1.113.0.48
|
||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||
nbproject/build-impl.xml.data.CRC32=36922983
|
||||
nbproject/build-impl.xml.script.CRC32=233b34c8
|
||||
nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.113.0.48
|
||||
|
|
@ -1,120 +0,0 @@
|
|||
annotation.processing.enabled=true
|
||||
annotation.processing.enabled.in.editor=false
|
||||
annotation.processing.processors.list=
|
||||
annotation.processing.run.all.processors=true
|
||||
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||
application.title=jNetServer
|
||||
application.vendor=cucky
|
||||
build.classes.dir=${build.dir}/classes
|
||||
build.classes.excludes=**/*.java,**/*.form
|
||||
# This directory is removed when the project is cleaned:
|
||||
build.dir=build
|
||||
build.generated.dir=${build.dir}/generated
|
||||
build.generated.sources.dir=${build.dir}/generated-sources
|
||||
# Only compile against the classpath explicitly listed here:
|
||||
build.sysclasspath=ignore
|
||||
build.test.classes.dir=${build.dir}/test/classes
|
||||
build.test.results.dir=${build.dir}/test/results
|
||||
# Uncomment to specify the preferred debugger connection transport:
|
||||
#debug.transport=dt_socket
|
||||
debug.classpath=\
|
||||
${run.classpath}
|
||||
debug.modulepath=\
|
||||
${run.modulepath}
|
||||
debug.test.classpath=\
|
||||
${run.test.classpath}
|
||||
debug.test.modulepath=\
|
||||
${run.test.modulepath}
|
||||
# Files in build.classes.dir which should be excluded from distribution jar
|
||||
dist.archive.excludes=
|
||||
# This directory is removed when the project is cleaned:
|
||||
dist.dir=dist
|
||||
dist.jar=${dist.dir}/jNetServer.jar
|
||||
dist.javadoc.dir=${dist.dir}/javadoc
|
||||
dist.jlink.dir=${dist.dir}/jlink
|
||||
dist.jlink.output=${dist.jlink.dir}/jNetServer
|
||||
endorsed.classpath=
|
||||
excludes=
|
||||
file.reference.apache-commons-configuration2-2.9.0.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\apache-commons-configuration2-2.9.0.jar
|
||||
file.reference.apache-commons-lang3-3.12.0.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\apache-commons-lang3-3.12.0.jar
|
||||
file.reference.apache-commons-logging-1.2.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\apache-commons-logging-1.2.jar
|
||||
file.reference.apache-commons-text-1.10.0.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\apache-commons-text-1.10.0.jar
|
||||
file.reference.icmp4j-all.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\icmp4j-all.jar
|
||||
file.reference.jna-5.3.1.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\jna-5.3.1.jar
|
||||
file.reference.jna-platform-5.9.0.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\jna-platform-5.9.0.jar
|
||||
file.reference.mysql-connector-java-8.0.15.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\mysql-connector-java-8.0.15.jar
|
||||
file.reference.netty-all-4.1.68.Final.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\netty-all-4.1.68.Final.jar
|
||||
file.reference.spring-security-crypto-5.8.0.jar=C:\\Users\\cucky\\Documents\\NetBeansProjects\\jar_files\\spring-security-crypto-5.8.0.jar
|
||||
includes=**
|
||||
jar.compress=false
|
||||
javac.classpath=\
|
||||
${file.reference.mysql-connector-java-8.0.15.jar}:\
|
||||
${reference.jNetLib.jar}:\
|
||||
${file.reference.apache-commons-lang3-3.12.0.jar}:\
|
||||
${file.reference.netty-all-4.1.68.Final.jar}:\
|
||||
${file.reference.icmp4j-all.jar}:\
|
||||
${file.reference.apache-commons-logging-1.2.jar}:\
|
||||
${file.reference.apache-commons-text-1.10.0.jar}:\
|
||||
${file.reference.jna-5.3.1.jar}:\
|
||||
${file.reference.jna-platform-5.9.0.jar}:\
|
||||
${file.reference.spring-security-crypto-5.8.0.jar}:\
|
||||
${file.reference.apache-commons-configuration2-2.9.0.jar}
|
||||
# Space-separated list of extra javac options
|
||||
javac.compilerargs=
|
||||
javac.deprecation=false
|
||||
javac.external.vm=true
|
||||
javac.modulepath=
|
||||
javac.processormodulepath=
|
||||
javac.processorpath=\
|
||||
${javac.classpath}
|
||||
javac.source=23
|
||||
javac.target=23
|
||||
javac.test.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
javac.test.modulepath=\
|
||||
${javac.modulepath}
|
||||
javac.test.processorpath=\
|
||||
${javac.test.classpath}
|
||||
javadoc.additionalparam=
|
||||
javadoc.author=false
|
||||
javadoc.encoding=${source.encoding}
|
||||
javadoc.html5=false
|
||||
javadoc.noindex=false
|
||||
javadoc.nonavbar=false
|
||||
javadoc.notree=false
|
||||
javadoc.private=false
|
||||
javadoc.splitindex=true
|
||||
javadoc.use=true
|
||||
javadoc.version=false
|
||||
javadoc.windowtitle=
|
||||
# The jlink additional root modules to resolve
|
||||
jlink.additionalmodules=
|
||||
# The jlink additional command line parameters
|
||||
jlink.additionalparam=
|
||||
jlink.launcher=true
|
||||
jlink.launcher.name=jNetServer
|
||||
main.class=jnet.server.Server
|
||||
manifest.file=manifest.mf
|
||||
meta.inf.dir=${src.dir}/META-INF
|
||||
mkdist.disabled=false
|
||||
platform.active=default_platform
|
||||
project.jNetLib=../jNetLib
|
||||
reference.jNetLib.jar=${project.jNetLib}/dist/jNetLib.jar
|
||||
run.classpath=\
|
||||
${javac.classpath}:\
|
||||
${build.classes.dir}
|
||||
# Space-separated list of JVM arguments used when running the project.
|
||||
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||
run.jvmargs=
|
||||
run.modulepath=\
|
||||
${javac.modulepath}
|
||||
run.test.classpath=\
|
||||
${javac.test.classpath}:\
|
||||
${build.test.classes.dir}
|
||||
run.test.modulepath=\
|
||||
${javac.test.modulepath}
|
||||
source.encoding=UTF-8
|
||||
src.dir=src
|
||||
test.src.dir=test
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||
<type>org.netbeans.modules.java.j2seproject</type>
|
||||
<configuration>
|
||||
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||
<name>jNetServer</name>
|
||||
<source-roots>
|
||||
<root id="src.dir"/>
|
||||
</source-roots>
|
||||
<test-roots>
|
||||
<root id="test.src.dir"/>
|
||||
</test-roots>
|
||||
</data>
|
||||
<references xmlns="http://www.netbeans.org/ns/ant-project-references/1">
|
||||
<reference>
|
||||
<foreign-project>jNetLib</foreign-project>
|
||||
<artifact-type>jar</artifact-type>
|
||||
<script>build.xml</script>
|
||||
<target>jar</target>
|
||||
<clean-target>clean</clean-target>
|
||||
<id>jar</id>
|
||||
</reference>
|
||||
</references>
|
||||
</configuration>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>jnet</groupId>
|
||||
<artifactId>jNetServer</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<exec.mainClass>jnet.server.Server</exec.mainClass>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
<version>4.1.118.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>1.78.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk18on</artifactId>
|
||||
<version>1.78.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jNetLib</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
<version>26.7.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>5.14.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-core</artifactId>
|
||||
<version>10.15.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.flywaydb</groupId>
|
||||
<artifactId>flyway-mysql</artifactId>
|
||||
<version>10.15.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<!-- Zakážeme standardní kopírování resources do target/classes -->
|
||||
<resources>
|
||||
<!-- prázdné -->
|
||||
</resources>
|
||||
|
||||
<finalName>jNetServer</finalName>
|
||||
|
||||
<plugins>
|
||||
<!-- Kopírování resources do target/ (vedle JARu) včetně podsložek -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-resources</id>
|
||||
<phase>process-resources</phase>
|
||||
<goals>
|
||||
<goal>copy-resources</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<outputDirectory>${project.build.directory}</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Shade plugin – vytvoří fat JAR a vyloučí naše resources -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.5.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<shadedArtifactAttached>false</shadedArtifactAttached>
|
||||
<shadedClassifierName>null</shadedClassifierName>
|
||||
<transformers>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>jnet.server.Server</mainClass>
|
||||
</transformer>
|
||||
</transformers>
|
||||
<filters>
|
||||
<!-- Vyřazení bezpečnostních podpisů ze všech artifactů -->
|
||||
<filter>
|
||||
<artifact>*:*</artifact>
|
||||
<excludes>
|
||||
<exclude>META-INF/*.SF</exclude>
|
||||
<exclude>META-INF/*.DSA</exclude>
|
||||
<exclude>META-INF/*.RSA</exclude>
|
||||
</excludes>
|
||||
</filter>
|
||||
<!-- Vyloučení veškerých resources z našeho vlastního artifactu -->
|
||||
<filter>
|
||||
<artifact>jnet:jNetServer</artifact>
|
||||
<excludes>
|
||||
<!-- Celé složky -->
|
||||
<exclude>db/**</exclude>
|
||||
<exclude>assets/**</exclude>
|
||||
<!-- Konkrétní soubory (a všechny s danou příponou) -->
|
||||
<exclude>**/*.properties</exclude>
|
||||
<exclude>**/*.dtd</exclude>
|
||||
<exclude>**/*.md</exclude>
|
||||
<exclude>**/*.service</exclude>
|
||||
<exclude>**/LICENSE</exclude>
|
||||
<exclude>**/README</exclude>
|
||||
<exclude>**/navod</exclude>
|
||||
<exclude>**/INFO_BIN</exclude>
|
||||
<exclude>**/INFO_SRC</exclude>
|
||||
<exclude>**/CONTRIBUTING.md</exclude>
|
||||
<!-- Pokud máte další soubory, přidejte je sem -->
|
||||
</excludes>
|
||||
</filter>
|
||||
</filters>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Kompilátor -->
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<release>${maven.compiler.release}</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -1,709 +0,0 @@
|
|||
package jnet.server;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.lib.object.Map;
|
||||
import jnet.lib.object.MapObject;
|
||||
import jnet.lib.object.ObjectType;
|
||||
import jnet.lib.object.SnmpProbe;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.lib.object.User;
|
||||
|
||||
public class Database {
|
||||
|
||||
private static Connection connection = null;
|
||||
private static String host;
|
||||
private static String port;
|
||||
private static String database;
|
||||
private static String user;
|
||||
private static String password;
|
||||
|
||||
|
||||
public void connect(String host, String port, String database, String user, String password) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.database = database;
|
||||
this.user = user;
|
||||
this.password = password;
|
||||
|
||||
connection = connect();
|
||||
}
|
||||
|
||||
private static Connection connect() {
|
||||
try {
|
||||
LogFile.printInfo("Connecting to a selected database ...");
|
||||
Connection connection = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + ""
|
||||
+ "?useUnicode=true"
|
||||
+ "&characterEncoding=UTF-8"
|
||||
+ "&autoReconnect=true"
|
||||
+ "&serverTimezone=UTC", user, password);
|
||||
LogFile.printInfo(" successfully");
|
||||
return connection;
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL connection exception: " + ex.getMessage());
|
||||
LogFile.printErr("MySQL host: " + host + " port: " + port + " database: " + database + " user: " + user);
|
||||
System.exit(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati aktualni spojeni
|
||||
*
|
||||
* @return
|
||||
* @throws SQLException
|
||||
*/
|
||||
public static Connection getCurrentConnection() throws SQLException {
|
||||
if (connection != null || connection.isClosed()) {
|
||||
return connection;
|
||||
} else {
|
||||
connection = connect();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* insert
|
||||
*
|
||||
* @param sql dotaz
|
||||
* @return pri uspesnem vlozeni vrati posledni vlozeny id
|
||||
*/
|
||||
public static int insert(String sqlQuery) {
|
||||
long id = -1;
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
statement.executeUpdate(sqlQuery, Statement.RETURN_GENERATED_KEYS);
|
||||
|
||||
PreparedStatement getLastInsertId = getCurrentConnection().prepareStatement("SELECT LAST_INSERT_ID()");
|
||||
ResultSet rs = getLastInsertId.executeQuery();
|
||||
if (rs.next()) {
|
||||
id = rs.getLong("last_insert_id()");
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + " SQL: " + sqlQuery);
|
||||
}
|
||||
return (int) id;
|
||||
}
|
||||
|
||||
/**
|
||||
* update
|
||||
*
|
||||
* @param sql sql dotaz
|
||||
*/
|
||||
public static void update(String sql) {
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
statement.executeUpdate(sql);
|
||||
statement.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + " SQL: " + sql);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* smaze zaznam z tabulky
|
||||
*
|
||||
* @param table nazev tabulky
|
||||
* @param id id rádku
|
||||
* @return
|
||||
*/
|
||||
static boolean remove(String table, int id) {
|
||||
try {
|
||||
String sql = "DELETE FROM " + table + " WHERE id = ?";
|
||||
|
||||
PreparedStatement stmt = getCurrentConnection().prepareStatement(sql);
|
||||
|
||||
stmt.setInt(1, id);
|
||||
|
||||
int affectedRows = stmt.executeUpdate();
|
||||
if (affectedRows > 0) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("Database error: " + ex.getMessage());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* vytvoří tabulku
|
||||
*
|
||||
* @param sql string
|
||||
*/
|
||||
public static void createTable(String sql) {
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
statement.executeUpdate(sql);
|
||||
} catch (SQLException e) {
|
||||
System.out.println("An error has occured on Table Creation: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* vráti seznam vsech map
|
||||
*
|
||||
* @return ArrayList<Map>
|
||||
*/
|
||||
public static ArrayList<Map> getMapList() {
|
||||
String sql = "SELECT * FROM maps";
|
||||
ArrayList<Map> list = new ArrayList<Map>();
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet rs = statement.executeQuery(sql);
|
||||
while (rs.next()) {
|
||||
Map m = new Map(
|
||||
rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
rs.getBoolean("locked"));
|
||||
list.add(m);
|
||||
}
|
||||
rs.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati seznam objektu odpovidajici mape
|
||||
*
|
||||
* @param mapId id mapy
|
||||
* @return ArrayList<MapObject>
|
||||
*/
|
||||
public static ArrayList<MapObject> getMapObject(int mapId) {
|
||||
ArrayList<MapObject> list = new ArrayList<>();
|
||||
String sql = "SELECT * FROM objects WHERE map = " + mapId;
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet r = statement.executeQuery(sql);
|
||||
while (r.next()) {
|
||||
int objId = r.getInt("id");
|
||||
list.add(new MapObject(
|
||||
objId,
|
||||
r.getString("name"),
|
||||
r.getInt("map"),
|
||||
r.getInt("objectType"),
|
||||
r.getString("ip"),
|
||||
r.getInt("x"),
|
||||
r.getInt("y"),
|
||||
r.getString("user"),
|
||||
r.getString("password"),
|
||||
r.getString("description"),
|
||||
r.getString("location"),
|
||||
r.getInt("snmpProfile"),
|
||||
getSnmpProbe(objId),
|
||||
(boolean) (r.getInt("active") == 1),
|
||||
(r.getInt("winbox") == 1),
|
||||
r.getString("winboxPort"),
|
||||
(boolean) (r.getInt("ssh") == 1),
|
||||
r.getString("sshPort"),
|
||||
(boolean) (r.getInt("web") == 1),
|
||||
r.getString("webPort"),
|
||||
r.getInt("webVerze"),
|
||||
(boolean) (r.getInt("telnet") == 1),
|
||||
r.getString("telnetPort"),
|
||||
(boolean) (r.getInt("sms") == 1),
|
||||
r.getString("smsPort"),
|
||||
r.getInt("smsVerze")
|
||||
));
|
||||
}
|
||||
r.close();
|
||||
statement.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati seznam objektu
|
||||
*
|
||||
* @return ArrayList<MapObject>
|
||||
*/
|
||||
public static ArrayList<MapObject> getAllMapObject() {
|
||||
ArrayList<MapObject> list = new ArrayList<>();
|
||||
String sql = "SELECT * FROM objects";
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet r = statement.executeQuery(sql);
|
||||
while (r.next()) {
|
||||
int objId = r.getInt("id");
|
||||
list.add(new MapObject(
|
||||
objId,
|
||||
r.getString("name"),
|
||||
r.getInt("map"),
|
||||
r.getInt("objectType"),
|
||||
r.getString("ip"),
|
||||
r.getInt("x"),
|
||||
r.getInt("y"),
|
||||
r.getString("user"),
|
||||
r.getString("password"),
|
||||
r.getString("description"),
|
||||
r.getString("location"),
|
||||
r.getInt("snmpProfile"),
|
||||
getSnmpProbe(objId),
|
||||
(boolean) (r.getInt("active") == 1),
|
||||
(r.getInt("winbox") == 1),
|
||||
r.getString("winboxPort"),
|
||||
(boolean) (r.getInt("ssh") == 1),
|
||||
r.getString("sshPort"),
|
||||
(boolean) (r.getInt("web") == 1),
|
||||
r.getString("webPort"),
|
||||
r.getInt("webVerze"),
|
||||
(boolean) (r.getInt("telnet") == 1),
|
||||
r.getString("telnetPort"),
|
||||
(boolean) (r.getInt("sms") == 1),
|
||||
r.getString("smsPort"),
|
||||
r.getInt("smsVerze")
|
||||
));
|
||||
}
|
||||
r.close();
|
||||
statement.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati seznam SNMP probe
|
||||
*
|
||||
* @return ArrayList<SnmpProbe>
|
||||
*/
|
||||
public static ArrayList<SnmpProbe> getSnmpProbe(int objId) {
|
||||
ArrayList<SnmpProbe> list = new ArrayList<>();
|
||||
String sql = "SELECT * FROM snmpProbe WHERE object = " + objId;
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet r = statement.executeQuery(sql);
|
||||
while (r.next()) {
|
||||
list.add(new SnmpProbe(
|
||||
r.getInt("id"),
|
||||
r.getString("name"),
|
||||
r.getInt("object")
|
||||
));
|
||||
}
|
||||
r.close();
|
||||
statement.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati informace o uzivateli podle jmena
|
||||
*
|
||||
* @param username
|
||||
* @return User
|
||||
*/
|
||||
static User getUserInfo(String username) {
|
||||
User u = null;
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet r_con = statement.executeQuery("SELECT * FROM users WHERE username = '" + username + "'");
|
||||
while (r_con.next()) {
|
||||
u = new User(r_con.getInt("id"),
|
||||
username,
|
||||
r_con.getString("password"),
|
||||
r_con.getBoolean("add_map"),
|
||||
r_con.getBoolean("remove_map"),
|
||||
r_con.getBoolean("edit_map"),
|
||||
r_con.getBoolean("add_object"),
|
||||
r_con.getBoolean("remove_object"),
|
||||
r_con.getBoolean("edit_object"),
|
||||
r_con.getBoolean("edit_server")
|
||||
);
|
||||
}
|
||||
r_con.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage());
|
||||
|
||||
}
|
||||
return u;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati seznam object type
|
||||
*
|
||||
* @return ArrayList<ObjectType>
|
||||
*/
|
||||
static ArrayList<ObjectType> getObjectType() {
|
||||
ArrayList<ObjectType> objectType = new ArrayList<>();
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet so = statement.executeQuery("SELECT * FROM objectType");
|
||||
while (so.next()) {
|
||||
objectType.add(new ObjectType(
|
||||
so.getInt("id"),
|
||||
so.getString("name"),
|
||||
so.getString("image")
|
||||
));
|
||||
}
|
||||
so.close();
|
||||
} catch (SQLException ex) {
|
||||
System.out.println("MySQL exception: " + ex.getMessage());
|
||||
}
|
||||
return objectType;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati seznam uzivatelu
|
||||
*
|
||||
* @return ArrayList<User>
|
||||
*/
|
||||
static ArrayList<User> getUsers() {
|
||||
ArrayList<User> users = new ArrayList<>();
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet su = statement.executeQuery("SELECT * FROM users");
|
||||
while (su.next()) {
|
||||
users.add(new User(
|
||||
su.getInt("id"),
|
||||
su.getString("username"),
|
||||
"",
|
||||
su.getBoolean("add_map"),
|
||||
su.getBoolean("remove_map"),
|
||||
su.getBoolean("edit_map"),
|
||||
su.getBoolean("add_object"),
|
||||
su.getBoolean("remove_object"),
|
||||
su.getBoolean("edit_object"),
|
||||
su.getBoolean("edit_server")
|
||||
));
|
||||
}
|
||||
su.close();
|
||||
} catch (SQLException ex) {
|
||||
System.out.println("MySQL exception: " + ex.getMessage());
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati snmp profily
|
||||
*
|
||||
* @return ArrayList<SnmpProfile>
|
||||
*/
|
||||
static ArrayList<SnmpProfile> getSnmpProfile() {
|
||||
ArrayList<SnmpProfile> snmpProfile = new ArrayList<>();
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet rs = statement.executeQuery("SELECT * FROM snmpProfile");
|
||||
while (rs.next()) {
|
||||
snmpProfile.add(new SnmpProfile(
|
||||
rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
rs.getInt("version"),
|
||||
rs.getString("port"),
|
||||
rs.getString("communityRead"),
|
||||
rs.getString("communityRead")
|
||||
));
|
||||
}
|
||||
rs.close();
|
||||
} catch (SQLException ex) {
|
||||
System.out.println("MySQL exception: " + ex.getMessage());
|
||||
}
|
||||
return snmpProfile;
|
||||
}
|
||||
|
||||
/**
|
||||
* vrati seznam udalosti
|
||||
*
|
||||
* @param
|
||||
* @return ArrayList<Event>
|
||||
*/
|
||||
public static ArrayList<Event> getEvents() {
|
||||
ArrayList<Event> list = new ArrayList<>();
|
||||
String sql = "SELECT * FROM events";
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
ResultSet r = statement.executeQuery(sql);
|
||||
while (r.next()) {
|
||||
list.add(new Event(
|
||||
r.getInt("id"),
|
||||
r.getInt("object"),
|
||||
r.getLong("start"),
|
||||
r.getLong("finish"),
|
||||
r.getString("description"),
|
||||
r.getInt("type")
|
||||
));
|
||||
}
|
||||
r.close();
|
||||
statement.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + "query: " + sql);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* pridá objekt
|
||||
*
|
||||
* @param mo MapObject
|
||||
* @return
|
||||
*/
|
||||
static MapObject addMapObject(MapObject mo) {
|
||||
String query = "INSERT INTO objects ("
|
||||
+ "name,"
|
||||
+ "ip,"
|
||||
+ "x,"
|
||||
+ "y,"
|
||||
+ "map,"
|
||||
+ "objectType,"
|
||||
+ "active,"
|
||||
+ "user,"
|
||||
+ "password,"
|
||||
+ "description,"
|
||||
+ "location,"
|
||||
+ "snmpProfile,"
|
||||
+ "winbox,"
|
||||
+ "winboxPort,"
|
||||
+ "ssh,"
|
||||
+ "sshPort,"
|
||||
+ "web,"
|
||||
+ "webPort,"
|
||||
+ "webVerze,"
|
||||
+ "telnet,"
|
||||
+ "telnetPort,"
|
||||
+ "sms,"
|
||||
+ "smsPort,"
|
||||
+ "smsVerze"
|
||||
+ ") VALUES ("
|
||||
+ "'" + mo.getName() + "',"
|
||||
+ "'" + mo.getIp() + "',"
|
||||
+ "'" + mo.getX() + "',"
|
||||
+ "'" + mo.getY() + "',"
|
||||
+ "'" + mo.getMap() + "',"
|
||||
+ "'" + mo.getObjectType() + "',"
|
||||
+ "'" + (mo.isActive() ? 1 : 0) + "',"
|
||||
+ "'" + mo.getUser() + "',"
|
||||
+ "'" + mo.getPassword() + "',"
|
||||
+ "'" + mo.getDescription() + "',"
|
||||
+ "'" + mo.getLocation() + "',"
|
||||
+ "'" + mo.getSnmpProfile() + "',"
|
||||
+ "'" + (mo.isWinbox() ? 1 : 0) + "',"
|
||||
+ "'" + mo.getWinboxPort() + "',"
|
||||
+ "'" + (mo.isSsh() ? 1 : 0) + "',"
|
||||
+ "'" + mo.getSshPort() + "',"
|
||||
+ "'" + (mo.isWeb() ? 1 : 0) + "',"
|
||||
+ "'" + mo.getWebPort() + "',"
|
||||
+ "'" + mo.getWebVerze() + "',"
|
||||
+ "'" + (mo.isTelnet() ? 1 : 0) + "',"
|
||||
+ "'" + mo.getTelnetPort() + "',"
|
||||
+ "'" + (mo.isSms() ? 1 : 0) + "',"
|
||||
+ "'" + mo.getSmsPort() + "',"
|
||||
+ "'" + mo.getSmsVerze() + "'"
|
||||
+ ")";
|
||||
mo.setId(insert(query));
|
||||
return mo;
|
||||
}
|
||||
|
||||
/**
|
||||
* nastaví stav zámku mapy
|
||||
*
|
||||
* @param state stav
|
||||
* @param map map id
|
||||
*/
|
||||
static void mapLock(int state, int map) {
|
||||
update("UPDATE maps SET locked='" + state + "' WHERE id=" + map);
|
||||
}
|
||||
|
||||
/**
|
||||
* pridá typ objektu
|
||||
*
|
||||
* @param ot ObjectType
|
||||
* @return
|
||||
*/
|
||||
static int addObjectType(ObjectType ot) {
|
||||
return insert("INSERT INTO objectType (name, image) VALUES ('" + ot.getName() + "', '" + ot.getImgStr() + "')");
|
||||
}
|
||||
|
||||
/**
|
||||
* odebere objekt z databaze
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
static void removeObject(int id) {
|
||||
if (remove("objects", id)) {
|
||||
LogFile.printInfo("Obejct ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Obejct ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* odebere mapu z databaze
|
||||
*
|
||||
* @param id
|
||||
*/
|
||||
static void removeMap(int id) {
|
||||
if (remove("maps", id)) {
|
||||
LogFile.printInfo("Map ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Map ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pridani mapy
|
||||
*
|
||||
* @param name nazev mapy
|
||||
* @return
|
||||
*/
|
||||
static int addMap(String name) {
|
||||
return insert("INSERT INTO maps (name) VALUES ('" + name + "')");
|
||||
}
|
||||
|
||||
/**
|
||||
* zmeni pozici objektu
|
||||
*
|
||||
* @param id id objektu
|
||||
* @param x pozice x
|
||||
* @param y pozice y
|
||||
*/
|
||||
static void objectMove(int id, int x, int y) {
|
||||
update("UPDATE objects SET x='" + x + "', y='" + y + "' WHERE id=" + id);
|
||||
}
|
||||
|
||||
/**
|
||||
* upravi object
|
||||
*
|
||||
* @param mo MapObject
|
||||
*/
|
||||
static void updateObject(MapObject mo) {
|
||||
update("UPDATE objects SET "
|
||||
+ "name='" + mo.getName() + "', "
|
||||
+ "ip='" + mo.getIp() + "', "
|
||||
+ "x='" + mo.getX() + "', "
|
||||
+ "y='" + mo.getY() + "',"
|
||||
+ "map='" + mo.getMap() + "', "
|
||||
+ "objectType='" + mo.getObjectType() + "', "
|
||||
+ "active='" + (mo.isActive() ? 1 : 0) + "', "
|
||||
+ "user='" + mo.getUser() + "', "
|
||||
+ "password='" + mo.getPassword() + "', "
|
||||
+ "description='" + mo.getDescription() + "', "
|
||||
+ "location='" + mo.getLocation() + "', "
|
||||
+ "snmpProfile='" + mo.getSnmpProfile() + "', "
|
||||
+ "winbox='" + (mo.isWinbox() ? 1 : 0) + "', "
|
||||
+ "winboxPort='" + mo.getWinboxPort() + "', "
|
||||
+ "ssh='" + (mo.isSsh() ? 1 : 0) + "', "
|
||||
+ "sshPort='" + mo.getSshPort() + "', "
|
||||
+ "web='" + (mo.isWeb() ? 1 : 0) + "', "
|
||||
+ "webPort='" + mo.getWebPort() + "', "
|
||||
+ "webVerze='" + mo.getWebVerze() + "', "
|
||||
+ "telnet='" + (mo.isTelnet() ? 1 : 0) + "', "
|
||||
+ "telnetPort='" + mo.getTelnetPort() + "', "
|
||||
+ "sms='" + (mo.isSms() ? 1 : 0) + "', "
|
||||
+ "smsPort='" + mo.getSmsPort() + "', "
|
||||
+ "smsVerze='" + mo.getSmsVerze() + "' "
|
||||
+ "WHERE id=" + mo.getId());
|
||||
}
|
||||
|
||||
public static Event addEvent(int mo_id, String description, int type) {
|
||||
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
|
||||
Event event = new Event(mo_id,
|
||||
timestamp.getTime(),
|
||||
description,
|
||||
type);
|
||||
int id = insert("INSERT INTO events ("
|
||||
+ "object, "
|
||||
+ "start, "
|
||||
+ "description, "
|
||||
+ "type"
|
||||
+ ") VALUES ("
|
||||
+ "'" + event.getObject() + "',"
|
||||
+ "'" + event.getStart() + "',"
|
||||
+ "'" + event.getDescription() + "',"
|
||||
+ "'" + event.getType() + "'"
|
||||
+ ")");
|
||||
event.setId(id);
|
||||
return event;
|
||||
|
||||
}
|
||||
|
||||
public static Event endEvent(int objectId, int type) {
|
||||
Event event = null;
|
||||
try {
|
||||
|
||||
String select_query = "SELECT * FROM events WHERE object = '" + objectId + "' && type = '" + type + "' ORDER BY id DESC LIMIT 1";
|
||||
PreparedStatement stmt = getCurrentConnection().prepareStatement(select_query);
|
||||
ResultSet rs = stmt.executeQuery();
|
||||
// Process the result
|
||||
if (rs.next()) {
|
||||
event = new Event(
|
||||
objectId,
|
||||
rs.getLong("start"),
|
||||
rs.getString("description"),
|
||||
type);
|
||||
event.setId(rs.getInt("id"));
|
||||
}
|
||||
Timestamp timestamp = new Timestamp(System.currentTimeMillis());
|
||||
event.setEnd(timestamp.getTime());
|
||||
String update_query = "UPDATE events SET finish='" + event.getEnd() + "' WHERE id=" + event.getId();
|
||||
update(update_query);
|
||||
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage());
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
static int addUser(User user) {
|
||||
return insert("INSERT INTO users ("
|
||||
+ "username, "
|
||||
+ "password, "
|
||||
+ "add_map, "
|
||||
+ "remove_map, "
|
||||
+ "edit_map, "
|
||||
+ "add_object, "
|
||||
+ "remove_object, "
|
||||
+ "edit_object, "
|
||||
+ "edit_server"
|
||||
+ ") VALUES ("
|
||||
+ "'"+user.getUsername()+"',"
|
||||
+ "'"+user.getPassword()+"',"
|
||||
+ "'"+(user.isAddMap()?1:0)+"',"
|
||||
+ "'"+(user.isRemoveMap()?1:0)+"',"
|
||||
+ "'"+(user.isEditMap()?1:0)+"',"
|
||||
+ "'"+(user.isAddObject()?1:0)+"',"
|
||||
+ "'"+(user.isRemoveObject()?1:0)+"',"
|
||||
+ "'"+(user.isEditObject()?1:0)+"',"
|
||||
+ "'"+(user.isEditServer()?1:0)+"'"
|
||||
+ ")");
|
||||
}
|
||||
|
||||
static void editUser(User ur) {
|
||||
String sql = "UPDATE users SET "
|
||||
+ "username='" + ur.getUsername() + "',"
|
||||
+ "add_map='" + (ur.isAddMap() ? 1:0) + "',"
|
||||
+ "remove_map='" + (ur.isRemoveMap() ? 1:0) + "',"
|
||||
+ "edit_map='" + (ur.isEditMap() ? 1:0) + "',"
|
||||
+ "add_object='" + (ur.isAddObject() ? 1:0) + "',"
|
||||
+ "remove_object='" + (ur.isEditObject() ? 1:0) + "',"
|
||||
+ "edit_object='" + (ur.isRemoveObject() ? 1:0) + "',"
|
||||
+ "edit_server='" + (ur.isEditServer() ? 1:0) + "'"
|
||||
+ "WHERE id='" + ur.getId() + "'";
|
||||
update(sql);
|
||||
}
|
||||
|
||||
static void deleteObjectLog(int objId) {
|
||||
String sql = "DELETE FROM events WHERE object = " + objId;
|
||||
try {
|
||||
Statement statement = getCurrentConnection().createStatement();
|
||||
statement.executeUpdate(sql);
|
||||
statement.close();
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL exception: " + ex.getMessage() + " SQL: " + sql);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,173 +0,0 @@
|
|||
package jnet.server;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import jnet.lib.BuilddDate;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.LogWindow;
|
||||
import jnet.lib.OSValidator;
|
||||
import jnet.lib.PropertiesManager;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.lib.object.Map;
|
||||
import jnet.lib.object.MapObject;
|
||||
import jnet.lib.object.ObjectType;
|
||||
import jnet.lib.object.OnlineClients;
|
||||
import jnet.lib.object.SnmpProbe;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.lib.object.User;
|
||||
import jnet.server.network.NettyServer;
|
||||
import jnet.server.probe.NettyPing;
|
||||
|
||||
public class Server {
|
||||
|
||||
// verze serveru
|
||||
public static final int SERVER_VERSION = 1;
|
||||
|
||||
// minimální verze klienta
|
||||
public static final int MINIMAL_CLIENT_VERSION = 1;
|
||||
|
||||
|
||||
public static PropertiesManager config;
|
||||
public static List<Map> maps = new ArrayList<>();
|
||||
public static ArrayList<MapObject> mapObject= new ArrayList<>();
|
||||
public static ArrayList<OnlineClients> onlineClients = new ArrayList<>();
|
||||
public static ArrayList<ObjectType> objectType = new ArrayList<>();
|
||||
public static ArrayList<SnmpProfile> snmpProfile = new ArrayList<>();
|
||||
public static ArrayList<SnmpProbe> snmpProbe = new ArrayList<>();
|
||||
public static ArrayList<User> users = new ArrayList<>();
|
||||
public static ArrayList<Event> events = new ArrayList<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
// pokud je hostitelsky system windows otevre logovaci okno
|
||||
if (OSValidator.isWindows()) {
|
||||
new LogWindow();
|
||||
}
|
||||
|
||||
|
||||
|
||||
LogFile.clear();
|
||||
LogFile.setDebug(false);
|
||||
LogFile.printInfo("---------------------------------------------");
|
||||
LogFile.printInfo(" jNet Server ");
|
||||
LogFile.printInfo(" Version: " + SERVER_VERSION + " (" + BuilddDate.get() + ")");
|
||||
LogFile.printInfo("---------------------------------------------");
|
||||
LogFile.printInfo("");
|
||||
|
||||
|
||||
///
|
||||
/// nahrani konfigurace
|
||||
///
|
||||
LogFile.printInfo("Loading config ...");
|
||||
try {
|
||||
// Načtení existující konfigurace, pokud soubor existuje
|
||||
config = new PropertiesManager("config.properties");
|
||||
config.load();
|
||||
LogFile.printInfo(" successfully");
|
||||
} catch (PropertiesManager.FileException | PropertiesManager.ConfigException ex) {
|
||||
LogFile.printErr(" fail. " + ex.getMessage());
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// debug rezim ?
|
||||
///
|
||||
if (config.getBoolean("debug")) {
|
||||
LogFile.setDebug(true);
|
||||
LogFile.printDebug("Debug mode on");
|
||||
}
|
||||
|
||||
///
|
||||
/// pripojeni k databazi
|
||||
///
|
||||
new Database().connect(config.getString("mysql_server"),
|
||||
config.getString("mysql_port"),
|
||||
config.getString("mysql_database"),
|
||||
config.getString("mysql_user"),
|
||||
config.getString("mysql_password"));
|
||||
|
||||
///
|
||||
/// konfigurace z databaze
|
||||
///
|
||||
LogFile.printInfo("Loading user list ...");
|
||||
users = Database.getUsers();
|
||||
LogFile.printInfo(" load " + users.size() + " user(s)");
|
||||
|
||||
LogFile.printInfo("Loading map list ...");
|
||||
maps = Database.getMapList();
|
||||
LogFile.printInfo(" load " + maps.size() + " map(s)");
|
||||
|
||||
LogFile.printInfo("Loading object list ...");
|
||||
mapObject = Database.getAllMapObject();
|
||||
LogFile.printInfo(" load " + mapObject.size() + " object(s)");
|
||||
|
||||
LogFile.printInfo("Loading object type ...");
|
||||
objectType = Database.getObjectType();
|
||||
LogFile.printInfo(" load " + objectType.size() + " type(s)");
|
||||
|
||||
LogFile.printInfo("Loading SNMP profile ...");
|
||||
snmpProfile = Database.getSnmpProfile();
|
||||
LogFile.printInfo(" load " + snmpProfile.size() + " profile(s)");
|
||||
|
||||
// LogFile.printInfo("Loading SNMP template ...");
|
||||
// snmpProbe = Database.getSnmpProbe();
|
||||
// LogFile.printInfo(" load " + snmpProbe.size() + " template(s)");
|
||||
|
||||
LogFile.printInfo("Loading events ...");
|
||||
events = Database.getEvents();
|
||||
LogFile.printInfo(" load " + events.size() + " event(s)");
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// spusteni serveru
|
||||
///
|
||||
NettyServer nettyserver = new NettyServer(config.getInt("server_port"));
|
||||
nettyserver.start();
|
||||
|
||||
///
|
||||
/// spusteni ping probe
|
||||
///
|
||||
/// spousete pro kazdou mapu samostatne ?
|
||||
///
|
||||
// Ping pp = new Ping();
|
||||
// pp.start();
|
||||
|
||||
// Ping2 p2 = new Ping2();
|
||||
// p2.start();
|
||||
|
||||
NettyPing np = new NettyPing();
|
||||
np.start();
|
||||
|
||||
}
|
||||
|
||||
public static void restartServer() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
try {
|
||||
String java = System.getProperty("java.home") + "/bin/java";
|
||||
File jarFile = new File(Server.class
|
||||
.getProtectionDomain().getCodeSource().getLocation().getPath());
|
||||
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add(java);
|
||||
command.add("-jar");
|
||||
command.add(jarFile.getAbsolutePath());
|
||||
|
||||
new ProcessBuilder(command).start();
|
||||
System.exit(0);
|
||||
} catch (IOException ex) {
|
||||
LogFile.printErr("Restart failed! " + ex.getMessage());
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
LogFile.printErr("Restart failed! " + e.getMessage());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,349 +0,0 @@
|
|||
package jnet.server;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.group.ChannelGroup;
|
||||
import io.netty.channel.group.DefaultChannelGroup;
|
||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.ListIterator;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.PasswordHashing;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.lib.object.Map;
|
||||
import jnet.lib.object.MapObject;
|
||||
import jnet.lib.object.ObjectType;
|
||||
import jnet.lib.object.OnlineClients;
|
||||
import jnet.lib.object.ServerConfig;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.lib.object.User;
|
||||
|
||||
public class ServerMessageParser {
|
||||
|
||||
private final Channel currentClient;
|
||||
private static final ChannelGroup channels = new DefaultChannelGroup(
|
||||
"containers", GlobalEventExecutor.INSTANCE);
|
||||
|
||||
public ServerMessageParser(Channel currentClient) {
|
||||
this.currentClient = currentClient;
|
||||
}
|
||||
|
||||
public void parse(Message msg) {
|
||||
|
||||
LogFile.printDebug("-> Message type: " + msg.getType());
|
||||
|
||||
ListIterator<Map> iteratorMap = Server.maps.listIterator();
|
||||
ListIterator<MapObject> iteratorMapObject = Server.mapObject.listIterator();
|
||||
|
||||
switch (msg.getType()) {
|
||||
|
||||
case Message.CLIENT_VERSION:
|
||||
int client_version = (int) msg.getMsg();
|
||||
if (client_version < Server.MINIMAL_CLIENT_VERSION) {
|
||||
LogFile.printInfo("Outdated client. Sent update request (" + ((InetSocketAddress) currentClient.remoteAddress()).getHostName() + ")");
|
||||
send(new Message(Message.UPDATE, null));
|
||||
} else {
|
||||
LogFile.printInfo("Authorization request send (" + ((InetSocketAddress) currentClient.remoteAddress()).getHostName() + ")");
|
||||
// oodeslat pozadavek na autorizacni udaje
|
||||
send(new Message(Message.AUTH_REQUEST, null));
|
||||
}
|
||||
break;
|
||||
|
||||
case Message.AUTH:
|
||||
String[] userData = (String[]) msg.getMsg();
|
||||
String username = userData[0];
|
||||
String password = userData[1];
|
||||
int platform = Integer.parseInt(userData[2]);
|
||||
|
||||
User u = Database.getUserInfo(username);
|
||||
|
||||
if (PasswordHashing.verify(password, u.getPassword())) {
|
||||
LogFile.printInfo("User: " + username + " logged in (" + ((InetSocketAddress) currentClient.remoteAddress()).getAddress().getHostName() + ")");
|
||||
// odeslat informaci uzivateli o jeho uspesnem prihlaseni
|
||||
send(new Message(Message.AUTH_SUCEFULL, null));
|
||||
// pridani uzivatele mezi pripojene kanaly
|
||||
channels.add(currentClient);
|
||||
// vložit uživatele na seznam online uživatelů
|
||||
InetSocketAddress socketAddress = (InetSocketAddress) currentClient.remoteAddress();
|
||||
String clientIp = socketAddress.getAddress().getHostAddress();
|
||||
String clientPort = String.valueOf(socketAddress.getPort());
|
||||
Server.onlineClients.add(new OnlineClients(
|
||||
String.valueOf(u.getId()),
|
||||
u.getUsername(),
|
||||
clientIp,
|
||||
clientPort,
|
||||
platform));
|
||||
// odeslat informace o prihlasenem uzivateli, opravneni atd
|
||||
send(new Message(Message.USER_INFO, u));
|
||||
// odeslat vsem nový seznam pripojenych klientu
|
||||
sendAll(new Message(Message.ONLINE_CLIENTS, Server.onlineClients));
|
||||
// odeslat nastaveni serveru
|
||||
ServerConfig sc = new ServerConfig(
|
||||
Server.config.getInt("ping_repeat"),
|
||||
Server.config.getInt("ping_attempt"),
|
||||
Server.config.getInt("ping_timeout"),
|
||||
Server.config.getInt("instability_attempt"),
|
||||
Server.config.getInt("instability_limit"));
|
||||
send(new Message(Message.SERVER_CONFIG, sc));
|
||||
// odeslat typy objektu
|
||||
for (ObjectType ot : Server.objectType) {
|
||||
send(new Message(Message.OBJECT_TYPE, ot));
|
||||
}
|
||||
// odesila seznam uzivatelu
|
||||
for (User us : Server.users) {
|
||||
send(new Message(Message.USER, us));
|
||||
}
|
||||
// odeslat seznam map
|
||||
for (Map i : Server.maps) {
|
||||
send(new Message(Message.MAP, i));
|
||||
}
|
||||
// odeslat seznam objektu
|
||||
send(Message.OBJECT_LIST, Server.mapObject);
|
||||
// odeslat seznam udalosti
|
||||
send(new Message(Message.EVENT_LIST, Server.events));
|
||||
// odeslat seznam snmp profilů
|
||||
for (SnmpProfile i : Server.snmpProfile) {
|
||||
send(new Message(Message.SNMP_PROFILE, i));
|
||||
}
|
||||
|
||||
} else {
|
||||
LogFile.printInfo("Authorization failed (ser: " + username + " )");
|
||||
}
|
||||
break;
|
||||
|
||||
case Message.RESTART:
|
||||
LogFile.printInfo("Prijat pozadavek na restart serveru");
|
||||
Server.restartServer();
|
||||
break;
|
||||
|
||||
case Message.UPTIME:
|
||||
long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
|
||||
send(Message.UPTIME, uptime);
|
||||
break;
|
||||
|
||||
case Message.NEW_OBJECT_TYPE:
|
||||
ObjectType not = (ObjectType) msg.getMsg();
|
||||
int id = Database.addObjectType(not);
|
||||
not.setId(id);
|
||||
Server.objectType.add(not);
|
||||
sendAll(new Message(Message.OBJECT_TYPE, not));
|
||||
break;
|
||||
|
||||
case Message.SET_MAP_LOCK:
|
||||
int[] data_lock = (int[]) msg.getMsg();
|
||||
while (iteratorMap.hasNext()) {
|
||||
Map map = iteratorMap.next();
|
||||
if (map.getId() == data_lock[0]) {
|
||||
map.setLock((data_lock[1] == 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// upravit informaci v databazi
|
||||
Database.mapLock(data_lock[1], data_lock[0]);
|
||||
// odeslani informace ostatnim
|
||||
sendAll(new Message(Message.SET_MAP_LOCK, data_lock));
|
||||
break;
|
||||
|
||||
case Message.ADD_OBJECT:
|
||||
MapObject mo = Database.addMapObject((MapObject) msg.getMsg());
|
||||
// pridat do seznamu
|
||||
Server.mapObject.add(mo);
|
||||
// odesle všem novy objekt
|
||||
sendAll(new Message(Message.ADD_OBJECT, mo));
|
||||
// prida event a odesle ho
|
||||
Event event = Database.addEvent(mo.getId(), "Přidáno", Event.TYPE_INFO);
|
||||
sendAll(new Message(Message.EVENT_NEW, event));
|
||||
// pokud je object vypnuty prida log
|
||||
if (!mo.isActive()) {
|
||||
Event event_disable = Database.addEvent(mo.getId(), "Ping vypnut", Event.TYPE_PING_OFF);
|
||||
sendAll(new Message(Message.EVENT_NEW, event_disable));
|
||||
}
|
||||
break;
|
||||
|
||||
case Message.REMOVE_OBJECT:
|
||||
while (iteratorMapObject.hasNext()) {
|
||||
MapObject obj = iteratorMapObject.next();
|
||||
if (obj.getId() == (int) msg.getMsg()) {
|
||||
// odebere z databaze
|
||||
Database.removeObject(obj.getId());
|
||||
// odesle informaci o odebrani objektu klientum
|
||||
sendAll(new Message(Message.REMOVE_OBJECT, obj.getId()));
|
||||
// odebere ze seznamu
|
||||
iteratorMapObject.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Message.MAP_REMOVE:
|
||||
while (iteratorMap.hasNext()) {
|
||||
Map map = iteratorMap.next();
|
||||
if (map.getId() == (int) msg.getMsg()) {
|
||||
// odebere z databaze
|
||||
Database.removeMap(map.getId());
|
||||
// odesle informaci o odebrani objektu klientum
|
||||
sendAll(new Message(Message.MAP_REMOVE, map.getId()));
|
||||
// odebere ze seznamu
|
||||
iteratorMap.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Message.MAP_ADD:
|
||||
Map map = new Map((String) msg.getMsg());
|
||||
// přidání mapy do databaze
|
||||
map.setId(Database.addMap(map.getName()));
|
||||
//odeslání mapy klientum
|
||||
send(new Message(Message.MAP, map));
|
||||
// pridani mapy do seznamu
|
||||
iteratorMap.add(map);
|
||||
break;
|
||||
|
||||
case Message.OBJECT_MOVE:
|
||||
int[] data = (int[]) msg.getMsg();
|
||||
// 0 = obj id
|
||||
// 2 = x
|
||||
// 2 = y
|
||||
// zmenit v databázi
|
||||
Database.objectMove(data[0], data[1], data[2]);
|
||||
// zmenit v seznamu
|
||||
while (iteratorMapObject.hasNext()) {
|
||||
MapObject obj = iteratorMapObject.next();
|
||||
if (obj.getId() == data[0]) {
|
||||
// zmenit pozici
|
||||
obj.setX(data[1]);
|
||||
obj.setY(data[2]);
|
||||
// zapsat zmenu do databaze
|
||||
Database.objectMove(data[0], data[1], data[2]);
|
||||
// preposlat zmenu klientum
|
||||
sendAll(new Message(Message.UPDATE_OBJECT, obj));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Message.UPDATE_OBJECT:
|
||||
MapObject mo_u = (MapObject) msg.getMsg();
|
||||
// zmenit v databazi
|
||||
Database.updateObject(mo_u);
|
||||
// zmenit v seznamu
|
||||
while (iteratorMapObject.hasNext()) {
|
||||
if (iteratorMapObject.next().getId() == mo_u.getId()) {
|
||||
iteratorMapObject.set(mo_u);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// preposlat zmenu klientum
|
||||
sendAll(new Message(Message.UPDATE_OBJECT, mo_u));
|
||||
break;
|
||||
|
||||
case Message.DELETE_LOG:
|
||||
int objId = (int) msg.getMsg();
|
||||
// vymaže logy v databazi
|
||||
Database.deleteObjectLog(objId);
|
||||
// vymaze logy v listu
|
||||
ListIterator<Event> iterator = Server.events.listIterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next().getObject() == objId) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
sendAll(new Message(Message.DELETE_LOG, objId));
|
||||
break;
|
||||
|
||||
case Message.USER:
|
||||
User user = (User) msg.getMsg();
|
||||
user.setPassword(PasswordHashing.hash(user.getPassword()));
|
||||
//pridáni do databáze a nastaveni id
|
||||
user.setId(Database.addUser(user));
|
||||
// přidání do seznamu
|
||||
Server.users.add(user);
|
||||
// odeslat klientum nového uživatele
|
||||
send(new Message(Message.USER, user));
|
||||
break;
|
||||
|
||||
case Message.USER_EDIT:
|
||||
User ue = (User) msg.getMsg();
|
||||
// upraveni v databázi
|
||||
Database.editUser(ue);
|
||||
// zmenit v seznamu
|
||||
ListIterator<User> iteratorUser = Server.users.listIterator();
|
||||
while (iteratorUser.hasNext()) {
|
||||
User next = iteratorUser.next();
|
||||
if (next.getId() == ue.getId()) {
|
||||
iteratorUser.set(ue);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// preposlat zmenu klientum
|
||||
sendAll(new Message(Message.USER_EDIT, ue));
|
||||
break;
|
||||
|
||||
case Message.SERVER_CONFIG:
|
||||
ServerConfig sc = (ServerConfig) msg.getMsg();
|
||||
// ulozeni
|
||||
Server.config.setInt("ping_repeat", sc.getPingRepeat());
|
||||
Server.config.setInt("ping_attempt", sc.getPingAttempt());
|
||||
Server.config.setInt("ping_timeout", sc.getPingTimeout());
|
||||
Server.config.setInt("instability_attempt", sc.getInstabilityAttempt());
|
||||
Server.config.setInt("instability_limit", sc.getInstabilityLimit());
|
||||
Server.config.save();
|
||||
//odeslani vsem
|
||||
sendAll(Message.SERVER_CONFIG, sc);
|
||||
break;
|
||||
|
||||
default:
|
||||
LogFile.printErr("Neznamy typ zpravy");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void send(Message message) {
|
||||
currentClient.writeAndFlush(message);
|
||||
LogFile.printDebug("<- Message type: " + message.getType());
|
||||
}
|
||||
|
||||
public void send(int type, Object obj) {
|
||||
currentClient.writeAndFlush(new Message(type, obj));
|
||||
LogFile.printDebug("<- Message type: " + type);
|
||||
}
|
||||
|
||||
public static void sendAll(Message message) {
|
||||
if (channels.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
channels.writeAndFlush(message);
|
||||
LogFile.printDebug("<- For all. Message type: " + message.getType());
|
||||
}
|
||||
|
||||
public static void sendAll(int type, Object obj) {
|
||||
if (channels.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
channels.writeAndFlush(new Message(type, obj));
|
||||
LogFile.printDebug("<- For all. Message type: " + type);
|
||||
}
|
||||
|
||||
public static final void removeClient(Channel ch) {
|
||||
// odebrani z připojenych kanalu
|
||||
channels.remove(ch);
|
||||
// odebrani ze seznamu klientu
|
||||
InetSocketAddress socketAddress = (InetSocketAddress) ch.remoteAddress();
|
||||
String clientIp = socketAddress.getAddress().getHostAddress();
|
||||
String clientPort = String.valueOf(socketAddress.getPort());
|
||||
for (OnlineClients oc : Server.onlineClients) {
|
||||
if (oc.getIp().equals(clientIp) && oc.getPort().equals(clientPort)) {
|
||||
Server.onlineClients.remove(oc);
|
||||
System.err.println("Client removed");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// odeslat vsem novy seznam klientu
|
||||
sendAll(new Message(Message.ONLINE_CLIENTS, Server.onlineClients));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
package jnet.server.network;
|
||||
|
||||
import jnet.lib.LogFile;
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.serialization.ClassResolvers;
|
||||
import io.netty.handler.codec.serialization.ObjectDecoder;
|
||||
import io.netty.handler.codec.serialization.ObjectEncoder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author cucky
|
||||
*/
|
||||
public class NettyServer extends Thread {
|
||||
|
||||
private int port;
|
||||
|
||||
public NettyServer(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
// Skupiny pro zpracování I/O operací
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
// Vytvoření ServerBootstrap pro nastavení serveru
|
||||
ServerBootstrap serverBootstrap = new ServerBootstrap()
|
||||
.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
//.handler(new LoggingHandler(LogLevel.INFO))
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) {
|
||||
ch.pipeline().addLast("decoder", new ObjectDecoder(ClassResolvers.weakCachingConcurrentResolver(getClass().getClassLoader())));
|
||||
ch.pipeline().addLast("encoder", new ObjectEncoder());
|
||||
ch.pipeline().addLast(new ServerHandler()); // Vlastní handler pro zpracování zpráv
|
||||
}
|
||||
});
|
||||
|
||||
// Bind serveru na specifikovaný port (např. 8080)
|
||||
Channel channel = serverBootstrap.bind(port).sync().channel();
|
||||
|
||||
LogFile.printInfo("Server is ready and listening on port " + port);
|
||||
|
||||
// Čekání na ukončení serveru
|
||||
channel.closeFuture().sync();
|
||||
} catch (Exception ex) {
|
||||
LogFile.printErr("Server exception: " + ex);
|
||||
} finally {
|
||||
// Uvolnění prostředků
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
package jnet.server.network;
|
||||
|
||||
import jnet.server.ServerMessageParser;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
|
||||
public class ServerHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
@Override
|
||||
public void channelRead(ChannelHandlerContext ctx, Object msg) {
|
||||
if (msg instanceof Message) {
|
||||
Message m = (Message) msg;
|
||||
new ServerMessageParser(ctx.channel()).parse((Message) msg);
|
||||
}
|
||||
if (msg instanceof String) {
|
||||
System.out.println("Client message: " + msg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
|
||||
System.out.println("Client connected");
|
||||
Channel currentClient = ctx.channel();
|
||||
currentClient.writeAndFlush(new Message(Message.CLIENT_VERSION, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
|
||||
LogFile.printInfo("Client disconnected");
|
||||
ServerMessageParser.removeClient(ctx.channel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
package jnet.server.network;
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.codec.string.StringDecoder;
|
||||
import io.netty.handler.codec.string.StringEncoder;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author cucky
|
||||
*/
|
||||
public class ServerSsl extends Thread {
|
||||
|
||||
private int port;
|
||||
|
||||
public ServerSsl(int port) {
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
try {
|
||||
|
||||
// Načtení self-signed certifikátu a privátního klíče
|
||||
//File certChainFile = new File("cert.pem");
|
||||
//File privateKeyFile = new File("key.pem");
|
||||
// Vytvoření SSL kontextu
|
||||
//SslContext sslContext = SslContextBuilder.forServer(certChainFile, privateKeyFile).build();
|
||||
|
||||
// Self-signed certifikát pro server
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
|
||||
// SSL kontext pro server
|
||||
SslContext sslContext = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey())
|
||||
.trustManager(InsecureTrustManagerFactory.INSTANCE) // Nepožadujeme důvěryhodné klientské certifikáty
|
||||
.build();
|
||||
// Skupiny pro zpracování I/O operací
|
||||
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
|
||||
EventLoopGroup workerGroup = new NioEventLoopGroup();
|
||||
try {
|
||||
// Vytvoření ServerBootstrap pro nastavení serveru
|
||||
ServerBootstrap serverBootstrap = new ServerBootstrap()
|
||||
.group(bossGroup, workerGroup)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
//.handler(new LoggingHandler(LogLevel.INFO))
|
||||
.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) {
|
||||
ch.pipeline().addLast(sslContext.newHandler(ch.alloc())); // SSL handler
|
||||
ch.pipeline().addLast(new StringDecoder()); // Dekóduje zprávy přijaté od klienta
|
||||
ch.pipeline().addLast(new StringEncoder()); // Kóduje zprávy odeslané klientovi
|
||||
ch.pipeline().addLast(new ServerHandler()); // Vlastní handler pro zpracování zpráv
|
||||
}
|
||||
});
|
||||
|
||||
// Bind serveru na specifikovaný port (např. 8080)
|
||||
Channel channel = serverBootstrap.bind(port).sync().channel();
|
||||
|
||||
System.out.println("ssl Server is ready and listening on port " + port);
|
||||
|
||||
// Čekání na ukončení serveru
|
||||
channel.closeFuture().sync();
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(ServerSsl.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
// Uvolnění prostředků
|
||||
bossGroup.shutdownGracefully();
|
||||
workerGroup.shutdownGracefully();
|
||||
}
|
||||
} catch (SSLException ex) {
|
||||
Logger.getLogger(ServerSsl.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (CertificateException ex) {
|
||||
Logger.getLogger(ServerSsl.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
package jnet.server.probe;
|
||||
|
||||
import io.netty.util.HashedWheelTimer;
|
||||
import io.netty.util.Timeout;
|
||||
import io.netty.util.TimerTask;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Status;
|
||||
import jnet.lib.object.MapObject;
|
||||
import jnet.server.Server;
|
||||
|
||||
public class NettyPing extends Thread {
|
||||
|
||||
private static final HashedWheelTimer TIMER = new HashedWheelTimer(); // Netty časovač
|
||||
|
||||
public NettyPing() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LogFile.printInfo("Ping probe start");
|
||||
for (MapObject mapObject : Server.mapObject) {
|
||||
schedulePing(mapObject);
|
||||
}
|
||||
}
|
||||
|
||||
private static void schedulePing(MapObject object) {
|
||||
TIMER.newTimeout(new TimerTask() {
|
||||
@Override
|
||||
public void run(Timeout timeout) {
|
||||
pingHost(object);
|
||||
timeout.timer().newTimeout(this, Server.config.getInt("ping_repeat"), TimeUnit.SECONDS); // Opakuje každých x sekund
|
||||
}
|
||||
}, 0, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private static void pingHost(MapObject object) {
|
||||
try {
|
||||
String command = System.getProperty("os.name").startsWith("Windows")
|
||||
? "ping -n 1 -w " + String.valueOf((Server.config.getInt("ping_timeout")*1000)) + " " + object.getIp() // Timeout 2000 ms (Windows)
|
||||
: "ping -c 1 -W " + String.valueOf(Server.config.getInt("ping_timeout")) + " " + object.getIp(); // Timeout 2 sec (Linux)
|
||||
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||
|
||||
String line;
|
||||
boolean success = false;
|
||||
int timeMs = -1;
|
||||
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (line.contains("TTL=") || line.contains("bytes from")) {
|
||||
success = true;
|
||||
timeMs = extractTime(line);
|
||||
}
|
||||
}
|
||||
|
||||
//System.out.println("Ping na " + object.getIp() + (success ? " uspesny! RTT: " + timeMs + " ms" : " selhal!"));
|
||||
if (success) {
|
||||
if (object.getStatus() != Status.OK) {
|
||||
PingResult.stateOnline(object);
|
||||
}
|
||||
} else {
|
||||
PingResult.stateOffline(object);
|
||||
}
|
||||
|
||||
process.waitFor();
|
||||
} catch (Exception e) {
|
||||
PingResult.stateOffline(object);
|
||||
LogFile.printErr("Chyba pri pingu na " + object.getIp() + " " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static int extractTime(String line) {
|
||||
String[] parts = line.split(" ");
|
||||
for (String part : parts) {
|
||||
if (part.contains("time=") || part.contains("čas=")) {
|
||||
return Integer.parseInt(part.replaceAll("[^0-9]", ""));
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
package jnet.server.probe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.Status;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.lib.object.MapObject;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.ServerMessageParser;
|
||||
|
||||
public class Ping extends Thread {
|
||||
|
||||
// Perioda opakování v sekundách
|
||||
private static final int PERIOD = 3;
|
||||
// Timeout pro ping (v milisekundách)
|
||||
private static final int TIMEOUT = 2000;
|
||||
// pocet pokus pro nastaveni offline statusu
|
||||
private static final int ATTEMPT = 3;
|
||||
|
||||
public Ping() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
// ExecutorService pro paralelní provádění pingů
|
||||
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||
|
||||
// ScheduledExecutorService pro periodické provádění
|
||||
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
|
||||
|
||||
// Naplánování periodického provádění kontrol
|
||||
scheduledExecutorService.scheduleAtFixedRate(() -> {
|
||||
for (MapObject mo : Server.mapObject) {
|
||||
if (mo.isActive()) {
|
||||
// Vytvoření úkolu pro pingování každé IP adresy
|
||||
executorService.submit(() -> {
|
||||
try {
|
||||
long responseTime = pingWithResponseTime(mo.getIp());
|
||||
if (responseTime >= 0) {
|
||||
isOnline(mo, responseTime);
|
||||
} else {
|
||||
isOffline(mo);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LogFile.printDebug("Chyba pri pingovani " + mo.getIp() + ": " + e.getMessage());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}, 0, PERIOD, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
// Funkce pro kontrolu dostupnosti IP adresy s timeoutem a zobrazení času odezvy
|
||||
private static long pingWithResponseTime(String ipAddress) throws IOException, InterruptedException {
|
||||
InetAddress inet = InetAddress.getByName(ipAddress);
|
||||
long startTime = System.currentTimeMillis(); // Začátek měření času
|
||||
boolean reachable = inet.isReachable(TIMEOUT); // Timeout pro ping 5 sekund
|
||||
long endTime = System.currentTimeMillis(); // Konec měření času
|
||||
|
||||
if (reachable) {
|
||||
return endTime - startTime; // Vrátí dobu odezvy v milisekundách
|
||||
} else {
|
||||
return -1; // Pokud není dostupná, vrátí -1
|
||||
}
|
||||
}
|
||||
|
||||
private void isOnline(MapObject mo, long responseTime) {
|
||||
// LogFile.printDebug(mo.getName() + "(" + mo.getIp() + ") online, latence: " + responseTime + " ms");
|
||||
// pokud neni predchozi stav ok odesle novy stav
|
||||
if (mo.getStatus() != Status.OK) {
|
||||
// pokud byl predchozi stav offline ukonci event
|
||||
if (mo.getStatus() == Status.OFFLINE) {
|
||||
// zapise do logu konec udalosti
|
||||
Event event = Database.endEvent(mo.getId(), Event.TYPE_PING);
|
||||
for (int i = 0; i < Server.events.size(); i++) {
|
||||
if (Server.events.get(i).getId() == event.getId()) {
|
||||
Server.events.set(i, event);
|
||||
ServerMessageParser.sendAll(new Message(Message.EVENT_UPDATE, (Event) event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// vynuluje počet pokusu o ping
|
||||
mo.setPingAttemp(0);
|
||||
// nastavi a odesle stav
|
||||
setNewState(mo, Status.OK);
|
||||
}
|
||||
// pokud byl predchozi stav N/A
|
||||
if (mo.getStatus() == Status.NA) {
|
||||
// nastavi a odesle stav
|
||||
setNewState(mo, Status.OK);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setNewState(MapObject mo, int state) {
|
||||
mo.setStatus(state);
|
||||
// odesle stav
|
||||
int[] o = {mo.getId(), state};
|
||||
ServerMessageParser.sendAll(new Message(Message.STATUS_UPDATE, o));
|
||||
}
|
||||
|
||||
private void isOffline(MapObject mo) {
|
||||
// zvysi pocet jiz probehlích pokusu o ping
|
||||
mo.pingAttemp++;
|
||||
|
||||
// vyhodnoti
|
||||
if (mo.getStatus() != Status.OFFLINE && mo.getPingAttemp() >= ATTEMPT) {
|
||||
int[] o = {mo.getId(), Status.OFFLINE};
|
||||
// nastavi objektu status
|
||||
mo.setStatus(Status.OFFLINE);
|
||||
// zapise do logu
|
||||
|
||||
// zapise do databaze
|
||||
Event event = Database.addEvent(mo.getId(), "offline", Event.TYPE_PING);
|
||||
Server.events.add(event);
|
||||
|
||||
//odesle stav a event klientum
|
||||
ServerMessageParser.sendAll(new Message(Message.STATUS_UPDATE, o));
|
||||
ServerMessageParser.sendAll(new Message(Message.EVENT_NEW, event));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
package jnet.server.probe;
|
||||
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.Status;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.lib.object.MapObject;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.ServerMessageParser;
|
||||
|
||||
public class PingResult {
|
||||
|
||||
private static final int POKUS = Server.config.getInt("ping_attempt");
|
||||
|
||||
public static void stateOnline(MapObject obj) {
|
||||
// oveří jestli neni zarizeni vypnuto
|
||||
if (obj.isActive() && obj.getStatus() != Status.OK) {
|
||||
// vynuluje ping pokusy
|
||||
obj.setPingAttemp(0);
|
||||
// pokud byl předchozí stav offline ukončí event
|
||||
if (obj.getStatus() == Status.OFFLINE) {
|
||||
// aktualizace eventu
|
||||
Event event = Database.endEvent(obj.getId(), Event.TYPE_PING);
|
||||
for (int i = 0; i < Server.events.size(); i++) {
|
||||
if (Server.events.get(i).getId() == event.getId()) {
|
||||
Server.events.set(i, event);
|
||||
}
|
||||
}
|
||||
// odeslani aktualizovaného eventu
|
||||
ServerMessageParser.sendAll(Message.EVENT_UPDATE, event);
|
||||
}
|
||||
|
||||
// nastavi status objektu
|
||||
obj.setStatus(Status.OK);
|
||||
// odesle informaci o novem stavu klientum
|
||||
sendState(obj.getId(), Status.OK);
|
||||
}
|
||||
}
|
||||
|
||||
public static void stateOffline(MapObject obj) {
|
||||
// oveří jestli neni zarizeni vypnuto
|
||||
if (obj.isActive()) {
|
||||
if (obj.getPingAttemp() >= POKUS && obj.getStatus() != Status.OFFLINE) {
|
||||
System.err.println("objekt: " + obj.getName() + " pokus: " + obj.getPingAttemp());
|
||||
// nastavi status objektu
|
||||
obj.setStatus(Status.OFFLINE);
|
||||
// odesle informaci o novem stavu klientum
|
||||
sendState(obj.getId(), Status.OFFLINE);
|
||||
// pridáni eventu
|
||||
Event event = Database.addEvent(obj.getId(), "Offline", Event.TYPE_PING);
|
||||
Server.events.add(event);
|
||||
// Odeslani eventu klientum
|
||||
ServerMessageParser.sendAll(new Message(Message.EVENT_NEW, event));
|
||||
} else {
|
||||
obj.pingAttemp++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendState(int object, int state) {
|
||||
int[] o = {object, state};
|
||||
ServerMessageParser.sendAll(new Message(Message.STATUS_UPDATE, o));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
package jnet.server;
|
||||
|
||||
import jnet.server.dao.SnmpDao;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.*;
|
||||
import jnet.server.dao.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Fasádní wrapper, který zachovává původní statické rozhraní třídy Database.
|
||||
* Všechny metody delegují na odpovídající DAO instance.
|
||||
*/
|
||||
public final class Database {
|
||||
|
||||
private static final UserDao userDao = new UserDao();
|
||||
private static final SiteDao siteDao = new SiteDao();
|
||||
private static final NodeDao nodeDao = new NodeDao();
|
||||
private static final EventDao eventDao = new EventDao();
|
||||
private static final SnmpDao snmpDao = new SnmpDao();
|
||||
private static final ObjectTypeDao objectTypeDao = new ObjectTypeDao();
|
||||
private static final ConnectionDao connectionDao = new ConnectionDao();
|
||||
private static final ProbeDao probeDao = new ProbeDao();
|
||||
|
||||
|
||||
// Veřejný konstruktor pro případy, kdy je v kódu voláno new Database()
|
||||
public Database() {}
|
||||
|
||||
///
|
||||
/// -------- inicializace --------
|
||||
///
|
||||
|
||||
public static void connect(String host, String port, String database, String user, String password) {
|
||||
ConnectionManager.init(host, port, database, user, password);
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- User --------
|
||||
///
|
||||
|
||||
public static boolean verifyUser(String username, String password) {
|
||||
return userDao.verifyUser(username, password);
|
||||
}
|
||||
|
||||
public static User getUserInfo(String username) {
|
||||
return userDao.getUserInfo(username);
|
||||
}
|
||||
|
||||
public static ArrayList<User> getUsers() {
|
||||
return new ArrayList<>(userDao.getUsers());
|
||||
}
|
||||
|
||||
public static int addUser(User user) {
|
||||
return userDao.addUser(user);
|
||||
}
|
||||
|
||||
public static void editUser(User u) {
|
||||
userDao.editUser(u);
|
||||
}
|
||||
|
||||
public static void deleteUser(int userId) {
|
||||
userDao.deleteUser(userId);
|
||||
}
|
||||
///
|
||||
/// -------- ObjectType --------
|
||||
///
|
||||
|
||||
public static ArrayList<DeviceType> getObjectType() {
|
||||
return new ArrayList<>(objectTypeDao.getObjectTypes());
|
||||
}
|
||||
|
||||
public static int addObjectType(DeviceType ot) {
|
||||
return objectTypeDao.addObjectType(ot);
|
||||
}
|
||||
|
||||
public static void deleteDeviceType(int id) {
|
||||
objectTypeDao.deleteDeviceType(id);
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- Site --------
|
||||
///
|
||||
|
||||
public static ArrayList<Site> getSiteList() {
|
||||
return new ArrayList<>(siteDao.getSiteList());
|
||||
}
|
||||
|
||||
public static int addSite(String name) {
|
||||
return siteDao.addSite(name);
|
||||
}
|
||||
|
||||
public static void removeSite(int id) {
|
||||
siteDao.removeSite(id);
|
||||
}
|
||||
|
||||
public static void setSiteLock(boolean state, int map) {
|
||||
siteDao.setSiteLock(state, map);
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- Node --------
|
||||
///
|
||||
|
||||
public static ArrayList<Node> getNodeList(int siteId) {
|
||||
return new ArrayList<>(nodeDao.getNodesForSite(siteId));
|
||||
}
|
||||
|
||||
public static int addNode(Node mo) {
|
||||
return nodeDao.addNode(mo);
|
||||
}
|
||||
|
||||
public static void removeNode(int id) {
|
||||
nodeDao.removeNode(id);
|
||||
}
|
||||
|
||||
public static void nodeUpdatePosition(int nodeId, int x, int y) {
|
||||
nodeDao.updatePosition(nodeId, x, y);
|
||||
}
|
||||
|
||||
public static void editNode(Node node) {
|
||||
nodeDao.updateNode(node);
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- NodeConnection (spojení) --------
|
||||
///
|
||||
|
||||
public static List<NodeConnection> getNodeConnectionList(int nodeId) {
|
||||
return connectionDao.getConnectionsForNode(nodeId);
|
||||
}
|
||||
|
||||
public static List<NodeConnection> getSiteConnectionList(int siteId) {
|
||||
return connectionDao.getConnectionsForSite(siteId);
|
||||
}
|
||||
|
||||
public static int addNodeConnection(NodeConnection nc) {
|
||||
return connectionDao.addConnection(nc);
|
||||
}
|
||||
|
||||
public static void removeNodeConnection(int id) {
|
||||
connectionDao.removeNodeConnection(id);
|
||||
}
|
||||
|
||||
public static void editNodeconnection(NodeConnection connection) {
|
||||
connectionDao.editNodeconnection(connection);
|
||||
}
|
||||
|
||||
public static void deteleConnectionAfterNodeMove(int id) {
|
||||
connectionDao.deteleConnectionAfterNodeMove(id);
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- Event --------
|
||||
///
|
||||
|
||||
public static long insertEvent(int nodeId, int status, long time) {
|
||||
return eventDao.insertEvent(nodeId, status, time);
|
||||
}
|
||||
|
||||
public static void endEvent(long eventId, long time) {
|
||||
eventDao.endEvent(eventId, time);
|
||||
}
|
||||
|
||||
public static List<Event> getAllEvents() {
|
||||
return eventDao.getAllEvents();
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- SNMP --------
|
||||
///
|
||||
|
||||
public static List<SnmpProfile> getSnmpProfile() {
|
||||
return snmpDao.getAllProfile();
|
||||
}
|
||||
|
||||
public static int addSnmpProfile(SnmpProfile profile) {
|
||||
return snmpDao.addSnmpProfile(profile);
|
||||
}
|
||||
|
||||
public static void editSnmpProfile(SnmpProfile profile) {
|
||||
snmpDao.editSnmpProfile(profile);
|
||||
}
|
||||
|
||||
public static void removeSnmpProfile(int id){
|
||||
snmpDao.removeSnmpProfile(id);
|
||||
}
|
||||
|
||||
public static List<SnmpTemplate> getSnmpTemplate(){
|
||||
return snmpDao.getSnmpTemplate();
|
||||
}
|
||||
|
||||
public static List<SnmpValueMap> getSnmpValueMapList() {
|
||||
return snmpDao.getSnmpValueMapList();
|
||||
}
|
||||
|
||||
public static int addSnmpTemplate(SnmpTemplate template) {
|
||||
return snmpDao.addSnmpTemplate(template);
|
||||
}
|
||||
|
||||
public static void editSnmpTemplate(SnmpTemplate template) {
|
||||
snmpDao.editSnmpTemplate(template);
|
||||
}
|
||||
|
||||
public static void deleteSnmpTemplate(int id) {
|
||||
snmpDao.deleteSnmpTemplate(id);
|
||||
}
|
||||
|
||||
public static int addSnmpValueMap(String name) {
|
||||
return snmpDao.addSnmpValueMap(name);
|
||||
}
|
||||
|
||||
public static int addSnmpValueMapItem(int map_id, String raw_value, String mapedValue) {
|
||||
return snmpDao.addSnmpValueMapItem(map_id, raw_value, mapedValue);
|
||||
}
|
||||
|
||||
public static void deleteSnmpValueMap(int id) {
|
||||
snmpDao.deleteSnmpValueMap(id);
|
||||
}
|
||||
|
||||
public static void editSnmpValueMap(SnmpValueMap valueMap) {
|
||||
snmpDao.editSnmpValueMap(valueMap);
|
||||
}
|
||||
|
||||
public static void deleteSnmpValueMapItem(int id) {
|
||||
snmpDao.deleteSnmpValueMapItem(id);
|
||||
}
|
||||
|
||||
public static void editSnmpValueMapItem(int map_id, String raw_value, String mapedValue) {
|
||||
snmpDao.editSnmpValueMapItem(map_id, raw_value, mapedValue);
|
||||
}
|
||||
|
||||
///
|
||||
/// -------- probe --------
|
||||
///
|
||||
|
||||
public static int addNodeProbe(NodeProbe probe) {
|
||||
return probeDao.addNodeProbe(probe);
|
||||
}
|
||||
|
||||
public static void removeNodeProbe(int id) {
|
||||
probeDao.removeNodeProbe(id);
|
||||
}
|
||||
|
||||
public static void editNodeProbe(NodeProbe probe) {
|
||||
probeDao.editNodeProbe(probe);
|
||||
}
|
||||
|
||||
// -------- zachování zastaralých metod pro kompatibilitu --------
|
||||
|
||||
@Deprecated
|
||||
public static void query(String sqlQuery) {
|
||||
try {
|
||||
siteDao.executeUpdate(sqlQuery); // používáme existující DAO instanci
|
||||
} catch (Exception e) {
|
||||
LogFile.printErr("MySQL exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int insert(String sqlQuery) {
|
||||
return siteDao.insertAndGetId(sqlQuery);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void update(String sql) {
|
||||
try {
|
||||
siteDao.executeUpdate(sql);
|
||||
} catch (Exception e) {
|
||||
LogFile.printErr("MySQL exception: " + e.getMessage() + " SQL: " + sql);
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
static boolean remove(String table, int id) {
|
||||
return siteDao.deleteById(table, id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
package jnet.server;
|
||||
|
||||
import jnet.lib.LogFile;
|
||||
import org.flywaydb.core.Flyway;
|
||||
import org.flywaydb.core.api.output.MigrateResult;
|
||||
|
||||
public class DatabaseMigrator {
|
||||
|
||||
public static void migrate(String jdbcUrl, String username, String password) {
|
||||
Flyway flyway = Flyway.configure()
|
||||
.dataSource(jdbcUrl, username, password)
|
||||
.locations("classpath:db/migration", "filesystem:db/migration")
|
||||
.load();
|
||||
|
||||
// Kontrola, zda je vše v pořádku
|
||||
flyway.validate();
|
||||
|
||||
// Provedení migrací
|
||||
MigrateResult migrationsApplied = flyway.migrate();
|
||||
}
|
||||
|
||||
static void migrate(String host, String port, String database, String username, String password) {
|
||||
String jdbcUrl = "jdbc:mysql://" + host + ":" + port + "/" + database + "?useSSL=false&serverTimezone=UTC";
|
||||
Flyway flyway = Flyway.configure()
|
||||
.dataSource(jdbcUrl, username, password)
|
||||
.locations("classpath:db/migration", "filesystem:db/migration")
|
||||
.ignoreMigrationPatterns("*:pending")
|
||||
.load();
|
||||
|
||||
// Kontrola, zda je vše v pořádku
|
||||
flyway.validate();
|
||||
|
||||
// Provedení migrací
|
||||
MigrateResult migrationsApplied = flyway.migrate();
|
||||
int successfully = migrationsApplied.getSuccessfulMigrations().size();
|
||||
int failed = migrationsApplied.getFailedMigrations().size();
|
||||
LogFile.printInfo(" Number of migrations performed: " + successfully);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package jnet.server;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.Status;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.server.networkserver.NettyServerManager;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class EventManager {
|
||||
|
||||
private static final Map<Integer, Long> openEventIds = new HashMap<>();
|
||||
|
||||
static public void insertOfflineEvent(int nodeId) {
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
long eventId = Database.insertEvent(nodeId, Status.OFFLINE, now);
|
||||
|
||||
if (eventId > 0) {
|
||||
openEventIds.put(nodeId, eventId);
|
||||
Event e = new Event(eventId, nodeId, Status.OFFLINE, now);
|
||||
Server.events.add(e);
|
||||
ServerHandler.sendAll(new Message(Message.EVENT_NEW, e));
|
||||
}
|
||||
}
|
||||
|
||||
static public void endEvent(int nodeId) {
|
||||
|
||||
Long eventId = openEventIds.get(nodeId);
|
||||
if (eventId != null) {
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
Database.endEvent(eventId, now);
|
||||
|
||||
openEventIds.remove(nodeId);
|
||||
|
||||
for (Event event : Server.events) {
|
||||
if (event.getId() == eventId) {
|
||||
event.setEnd(now);
|
||||
ServerHandler.sendAll(new Message(Message.EVENT_UPDATE, event));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
package jnet.server;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
import jnet.lib.ApacheConfig;
|
||||
import org.apache.commons.configuration2.Configuration;
|
||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
||||
import jnet.lib.BuilddDate;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.DeviceType;
|
||||
import jnet.lib.object.Event;
|
||||
import jnet.lib.object.OnlineClients;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.lib.object.User;
|
||||
import jnet.server.networkserver.NettyServerManager;
|
||||
import jnet.server.probe.Ping;
|
||||
import jnet.server.trafficmonitor.SnmpMonitorService;
|
||||
import jnet.lib.object.SnmpTemplate;
|
||||
import jnet.lib.object.SnmpValueMap;
|
||||
import jnet.server.probe.snmp.SnmpBatchProcessor;
|
||||
import jnet.server.probe.snmp.NodeProbeManager;
|
||||
|
||||
public class Server {
|
||||
|
||||
// verze serveru
|
||||
public static final int VERSION = 3;
|
||||
// minimální verze klienta
|
||||
public static final int MINIMAL_CLIENT_VERSION = 1;
|
||||
|
||||
public static Configuration config;
|
||||
|
||||
public static Database database;
|
||||
public static SnmpMonitorService trafficMonitorService;
|
||||
public static NodeProbeManager snmpProbeManager;
|
||||
|
||||
public static List<OnlineClients> onlineClients = new ArrayList<>();
|
||||
public static List<Site> site = new ArrayList<>();
|
||||
public static List<DeviceType> devicType = new ArrayList<>();
|
||||
public static List<SnmpProfile> snmpProfile = new ArrayList<>();
|
||||
public static List<User> users = new ArrayList<>();
|
||||
public static List<Event> events = new ArrayList<>();
|
||||
public static List<SnmpTemplate> snmpTemplate = new ArrayList<>();
|
||||
public static List<SnmpValueMap> snmpValueMap = new ArrayList<>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Prague"));
|
||||
|
||||
LogFile.clear();
|
||||
LogFile.setDebug(false);
|
||||
LogFile.printInfo("---------------------------------------------");
|
||||
LogFile.printInfo(" jNet Server ");
|
||||
LogFile.printInfo(" Version: " + VERSION + " (" + BuilddDate.get() + ")");
|
||||
LogFile.printInfo("---------------------------------------------");
|
||||
LogFile.printInfo("");
|
||||
|
||||
// Nahrani konfigurace
|
||||
LogFile.printInfo("Loading config ...");
|
||||
try {
|
||||
config = ApacheConfig.loadProperties();
|
||||
LogFile.printInfo(" successfully");
|
||||
} catch (ConfigurationException ex) {
|
||||
LogFile.printInfo(" fail: " + ex.getMessage());
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
// Debug mode
|
||||
if (config.getBoolean("debug")) {
|
||||
LogFile.setDebug(true);
|
||||
LogFile.printDebug("Debug mode on");
|
||||
}
|
||||
|
||||
// migrace databáze
|
||||
LogFile.printInfo("Ugrade database ...");
|
||||
DatabaseMigrator.migrate(
|
||||
config.getString("mysql_server"),
|
||||
config.getString("mysql_port"),
|
||||
config.getString("mysql_database"),
|
||||
config.getString("mysql_user"),
|
||||
config.getString("mysql_password")
|
||||
);
|
||||
|
||||
|
||||
// Pripojeni k databazi
|
||||
database = new Database();
|
||||
database.connect(
|
||||
config.getString("mysql_server"),
|
||||
config.getString("mysql_port"),
|
||||
config.getString("mysql_database"),
|
||||
config.getString("mysql_user"),
|
||||
config.getString("mysql_password")
|
||||
);
|
||||
|
||||
|
||||
// nacteni uzivatelu
|
||||
LogFile.printInfo("Loading user list ...");
|
||||
users = Database.getUsers();
|
||||
LogFile.printInfo(" load " + users.size() + " user(s)");
|
||||
|
||||
// nacteni node icon
|
||||
LogFile.printInfo("Loading node icon ...");
|
||||
devicType = Database.getObjectType();
|
||||
LogFile.printInfo(" load " + devicType.size() + " icon(s)");
|
||||
|
||||
// nacteni map a objektu z databaze
|
||||
LogFile.printInfo("Loading map and object list ...");
|
||||
site = Database.getSiteList();
|
||||
LogFile.printInfo(" load " + site.size() + " maps");
|
||||
|
||||
// nacteni logu
|
||||
LogFile.printInfo("Loading events list ...");
|
||||
events = Database.getAllEvents();
|
||||
LogFile.printInfo(" load " + events.size() + " events");
|
||||
|
||||
// nacteni SNMP profilu
|
||||
LogFile.printInfo("Loading SNMP profile list ...");
|
||||
snmpProfile = Database.getSnmpProfile();
|
||||
LogFile.printInfo(" load " + snmpProfile.size() + " profile(s)");
|
||||
|
||||
// nacteni SNMP sablon
|
||||
LogFile.printInfo("Loading SNMP template list ...");
|
||||
snmpTemplate = Database.getSnmpTemplate();
|
||||
LogFile.printInfo(" load " + snmpTemplate.size() + " templates(s)");
|
||||
|
||||
// nacteni SNMP sablon -value map
|
||||
LogFile.printInfo("Loading SNMP template value map list ...");
|
||||
snmpValueMap = Database.getSnmpValueMapList();
|
||||
LogFile.printInfo(" load " + snmpValueMap.size() + " value map(s)");
|
||||
|
||||
// ============================================================
|
||||
// 🆕 SPUŠTĚNÍ traffic SNMP MONITORU
|
||||
// ============================================================
|
||||
// Spustíme SNMP monitoring s intervalem z configu (např. 30 sekund)
|
||||
int snmpInterval = config.getInt("traffic_interval", 30) * 1000; // default 30s
|
||||
int batchInterval = config.getInt("traffic_batch_interval", 2) * 1000;
|
||||
trafficMonitorService.start(snmpInterval, batchInterval);
|
||||
// ============================================================
|
||||
|
||||
// Vytvoření SnmpProbeManager
|
||||
snmpProbeManager = new NodeProbeManager();
|
||||
|
||||
// Vytvoření batch processoru s intervalem 5 sekund (lze z configu)
|
||||
int batchSeconds = config.getInt("probe_batch_interval", 5);
|
||||
SnmpBatchProcessor batchProcessor = new SnmpBatchProcessor(batchSeconds);
|
||||
batchProcessor.init(snmpProbeManager); // zaregistruje se a spustí scheduler
|
||||
|
||||
|
||||
// spustěni ping probe
|
||||
Ping.start();
|
||||
|
||||
// Netty server vlákna
|
||||
NettyServerManager nettyServer = new NettyServerManager();
|
||||
nettyServer.start(config.getInt("server_port", 8443));
|
||||
|
||||
// Shutdown hook pro případ vypnutí z OS (Ctrl+C, kill/SIGTERM)
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||
LogFile.printInfo("Shutdown signal received...");
|
||||
// 🆕 Zastavení SNMP monitoru
|
||||
trafficMonitorService.stop();
|
||||
snmpProbeManager.close();
|
||||
nettyServer.stop();
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package jnet.server;
|
||||
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeState;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class SiteOperation {
|
||||
|
||||
public static void updateNodeStatus(NodeState ns){
|
||||
// zmení status v seznamu
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
if (node.getId() == ns.getId()) {
|
||||
node.setStatus(ns.getState());
|
||||
break; // ID je unikátní, po nalezení končíme
|
||||
}
|
||||
}
|
||||
}
|
||||
ServerHandler.sendAll(new Message(Message.NODE_STATUS_CHANGE, ns));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import jnet.lib.LogFile;
|
||||
import java.sql.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class AbstractDao {
|
||||
|
||||
protected Connection getConnection() throws SQLException {
|
||||
return ConnectionManager.getConnection();
|
||||
}
|
||||
|
||||
// -------- veřejné helpery pro všechny potomky i fasádu --------
|
||||
public int insertAndGetId(String sql, Object... params) {
|
||||
try (PreparedStatement pstmt = getConnection().prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
|
||||
setParameters(pstmt, params);
|
||||
//System.err.println(pstmt.toString());
|
||||
pstmt.executeUpdate();
|
||||
try (ResultSet rs = pstmt.getGeneratedKeys()) {
|
||||
if (rs.next()) {
|
||||
return rs.getInt(1);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Insert failed: " + e.getMessage() + " SQL: " + sql);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean deleteById(String table, int id) {
|
||||
String sql = "DELETE FROM " + table + " WHERE id = ?";
|
||||
try (PreparedStatement pstmt = getConnection().prepareStatement(sql)) {
|
||||
pstmt.setInt(1, id);
|
||||
return pstmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Delete failed: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void executeUpdate(String sql, Object... params) throws SQLException {
|
||||
try (PreparedStatement pstmt = getConnection().prepareStatement(sql)) {
|
||||
setParameters(pstmt, params);
|
||||
pstmt.executeUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteConnectionsByNodeId(String table, int nodeId) {
|
||||
String sql = "DELETE FROM " + table + " WHERE nodeFrom = ? OR nodeTo = ?";
|
||||
try (PreparedStatement pstmt = getConnection().prepareStatement(sql)) {
|
||||
pstmt.setInt(1, nodeId);
|
||||
pstmt.setInt(2, nodeId);
|
||||
return pstmt.executeUpdate() > 0;
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Delete connections failed: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// -------- chráněné helpery pro query (zůstávají protected) --------
|
||||
protected <T> T querySingle(String sql, ResultSetMapper<T> mapper, Object... params) {
|
||||
try (PreparedStatement pstmt = getConnection().prepareStatement(sql)) {
|
||||
setParameters(pstmt, params);
|
||||
try (ResultSet rs = pstmt.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
return mapper.map(rs);
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Query failed: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected <T> List<T> queryList(String sql, ResultSetMapper<T> mapper, Object... params) {
|
||||
List<T> list = new ArrayList<>();
|
||||
try (PreparedStatement pstmt = getConnection().prepareStatement(sql)) {
|
||||
setParameters(pstmt, params);
|
||||
try (ResultSet rs = pstmt.executeQuery()) {
|
||||
while (rs.next()) {
|
||||
list.add(mapper.map(rs));
|
||||
}
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Query failed: " + e.getMessage());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private void setParameters(PreparedStatement pstmt, Object... params) throws SQLException {
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
pstmt.setObject(i + 1, params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface ResultSetMapper<T> {
|
||||
|
||||
T map(ResultSet rs) throws SQLException;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import jnet.lib.object.NodeConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.Node;
|
||||
|
||||
public class ConnectionDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "connection";
|
||||
|
||||
/**
|
||||
* Pro daný seznam uzlů vrátí všechna jejich spojení (bez duplicit).
|
||||
*/
|
||||
public List<NodeConnection> getConnectionsForNodes(List<Node> nodes) {
|
||||
return getUniqueConnectionsForNodes(nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí všechna spojení, do kterých daný uzel vstupuje nebo z nich
|
||||
* vystupuje.
|
||||
*/
|
||||
public List<NodeConnection> getConnectionsForNode(int nodeId) {
|
||||
String sql = "SELECT DISTINCT * FROM " + TABLE + " WHERE nodeFrom = ? OR nodeTo = ?";
|
||||
return queryList(sql, rs -> new NodeConnection(
|
||||
rs.getInt("id"),
|
||||
rs.getInt("siteId"),
|
||||
rs.getInt("nodeFrom"),
|
||||
rs.getInt("nodeTo"),
|
||||
rs.getInt("typeConnection"),
|
||||
rs.getBoolean("readTraffic"),
|
||||
rs.getInt("trafficNode"),
|
||||
rs.getInt("trafficIface")
|
||||
), nodeId, nodeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí všechna spojení, která mají alespoň jeden konec v seznamu uzlů.
|
||||
* Používá se pro efektivní načtení všech spojení na mapě najednou.
|
||||
*/
|
||||
public List<NodeConnection> getConnectionsForNodeList(List<Integer> nodeIds) {
|
||||
if (nodeIds == null || nodeIds.isEmpty()) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
// Sestavíme dynamický IN dotaz
|
||||
StringBuilder sql = new StringBuilder("SELECT DISTINCT * FROM " + TABLE + " WHERE nodeFrom IN (");
|
||||
for (int i = 0; i < nodeIds.size(); i++) {
|
||||
sql.append("?");
|
||||
if (i < nodeIds.size() - 1) {
|
||||
sql.append(",");
|
||||
}
|
||||
}
|
||||
sql.append(") OR nodeTo IN (");
|
||||
for (int i = 0; i < nodeIds.size(); i++) {
|
||||
sql.append("?");
|
||||
if (i < nodeIds.size() - 1) {
|
||||
sql.append(",");
|
||||
}
|
||||
}
|
||||
sql.append(")");
|
||||
|
||||
// Parametry: dvakrát stejný seznam
|
||||
List<Object> params = new ArrayList<>();
|
||||
params.addAll(nodeIds);
|
||||
params.addAll(nodeIds);
|
||||
|
||||
return queryList(sql.toString(), rs -> new NodeConnection(
|
||||
rs.getInt("id"),
|
||||
rs.getInt("siteId"),
|
||||
rs.getInt("nodeFrom"),
|
||||
rs.getInt("nodeTo"),
|
||||
rs.getInt("typeConnection"),
|
||||
rs.getBoolean("readTraffic"),
|
||||
rs.getInt("trafficNode"),
|
||||
rs.getInt("trafficIface")
|
||||
), params.toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí unikátní spojení pro daný seznam uzlů podle node ID (bez duplicit).
|
||||
*/
|
||||
public List<NodeConnection> getUniqueConnectionsForNodes(List<Node> nodes) {
|
||||
List<Integer> ids = new ArrayList<>();
|
||||
for (Node n : nodes) {
|
||||
ids.add(n.getId());
|
||||
}
|
||||
List<NodeConnection> all = getConnectionsForNodeList(ids);
|
||||
// odstranění duplicit podle id
|
||||
Set<Integer> seen = new HashSet<>();
|
||||
List<NodeConnection> unique = new ArrayList<>();
|
||||
for (NodeConnection nc : all) {
|
||||
if (seen.add(nc.getId())) {
|
||||
unique.add(nc);
|
||||
}
|
||||
}
|
||||
return unique;
|
||||
}
|
||||
|
||||
public int addConnection(NodeConnection nc) {
|
||||
String sql = "INSERT INTO " + TABLE + " (siteId, nodeFrom, nodeTo, typeConnection, readTraffic, trafficNode, trafficIface) "
|
||||
+ "VALUES (?,?,?,?,?,?,?)";
|
||||
return insertAndGetId(sql,
|
||||
nc.getSite(),
|
||||
nc.getNodeFrom(),
|
||||
nc.getNodeTo(),
|
||||
nc.getType(),
|
||||
(nc.isReadTraffic() ? 1:0),
|
||||
nc.getTrafficNode(),
|
||||
nc.getTrafficIface()
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí unikátní spojení pro danou site
|
||||
*/
|
||||
public List<NodeConnection> getConnectionsForSite(int siteId) {
|
||||
String sql = "SELECT * FROM " + TABLE + " WHERE siteId = ?";
|
||||
return queryList(sql, rs -> new NodeConnection(
|
||||
rs.getInt("id"),
|
||||
rs.getInt("siteId"),
|
||||
rs.getInt("nodeFrom"),
|
||||
rs.getInt("nodeTo"),
|
||||
rs.getInt("typeConnection"),
|
||||
rs.getBoolean("readTraffic"),
|
||||
rs.getInt("trafficNode"),
|
||||
rs.getInt("trafficIface")
|
||||
), siteId);
|
||||
}
|
||||
|
||||
public void removeNodeConnection(int id) {
|
||||
if (deleteById(TABLE, id)) {
|
||||
LogFile.printInfo("Node connection ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Node connection ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public void editNodeconnection(NodeConnection connection) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE + " SET typeConnection=?, readTraffic=?, trafficNode=?, trafficIface=? WHERE id=?",
|
||||
connection.getType(),
|
||||
(connection.isReadTraffic() ? 1:0),
|
||||
connection.getTrafficNode(),
|
||||
connection.getTrafficIface(),
|
||||
connection.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci connection: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deteleConnectionAfterNodeMove(int id) {
|
||||
if (deleteConnectionsByNodeId(TABLE, id)) {
|
||||
LogFile.printInfo("Node connection ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Node connection ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import jnet.lib.LogFile;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public final class ConnectionManager {
|
||||
|
||||
private static final int VALIDATION_TIMEOUT = 2;
|
||||
|
||||
private static String host;
|
||||
private static String port;
|
||||
private static String database;
|
||||
private static String user;
|
||||
private static String password;
|
||||
private static Connection connection = null;
|
||||
|
||||
private ConnectionManager() {}
|
||||
|
||||
public static void init(String host, String port, String database, String user, String password) {
|
||||
ConnectionManager.host = host;
|
||||
ConnectionManager.port = port;
|
||||
ConnectionManager.database = database;
|
||||
ConnectionManager.user = user;
|
||||
ConnectionManager.password = password;
|
||||
connection = createConnection();
|
||||
}
|
||||
|
||||
private static Connection createConnection() {
|
||||
try {
|
||||
String url = String.format(
|
||||
"jdbc:mysql://%s:%s/%s?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Europe/Prague",
|
||||
host, port, database
|
||||
);
|
||||
LogFile.printInfo("Connecting to database ...");
|
||||
Connection conn = DriverManager.getConnection(url, user, password);
|
||||
LogFile.printInfo(" successfully");
|
||||
return conn;
|
||||
} catch (SQLException ex) {
|
||||
LogFile.printErr("MySQL connection exception: " + ex.getMessage());
|
||||
System.exit(1);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí platné spojení – pokud je staré uzavřené (timeout), automaticky ho obnoví.
|
||||
*/
|
||||
public static Connection getConnection() throws SQLException {
|
||||
if (connection == null || !connection.isValid(VALIDATION_TIMEOUT)) {
|
||||
LogFile.printInfo("Database connection lost, reconnecting...");
|
||||
connection = createConnection();
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.Event;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
|
||||
public class EventDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "events";
|
||||
|
||||
public long insertEvent(int nodeId, int status, long time) {
|
||||
String sql = "INSERT INTO " + TABLE + " (node, status, start) VALUES (?, ?, ?)";
|
||||
return insertAndGetId(sql, nodeId, status, new Timestamp(time));
|
||||
}
|
||||
|
||||
public void endEvent(long eventId, long time) {
|
||||
try {
|
||||
executeUpdate("UPDATE events SET end = ? WHERE id = ?", new Timestamp(time), eventId);
|
||||
} catch (Exception e) {
|
||||
LogFile.printErr("MySQL exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public List<Event> getAllEvents() {
|
||||
String sql = "SELECT * FROM " + TABLE;
|
||||
return queryList(sql, rs -> {
|
||||
Timestamp start = rs.getTimestamp("start");
|
||||
Timestamp end = rs.getTimestamp("end");
|
||||
long startMillis = start.getTime();
|
||||
Long endMillis = (end != null) ? end.getTime() : 0L;
|
||||
return new Event(
|
||||
rs.getLong("id"),
|
||||
rs.getInt("node"),
|
||||
rs.getInt("status"),
|
||||
startMillis,
|
||||
endMillis,
|
||||
rs.getInt("duration")
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Status;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeProbe;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
public class NodeDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "node";
|
||||
|
||||
|
||||
public List<Node> getNodesForSite(int siteId) {
|
||||
String sql = "SELECT * FROM " + TABLE + " WHERE siteId = ?";
|
||||
return queryList(sql, this::mapNode, siteId);
|
||||
}
|
||||
|
||||
|
||||
public int addNode(Node node) {
|
||||
String sql = "INSERT INTO " + TABLE + " (name, ip, x, y, type, siteId, icon, ping, user, password, "
|
||||
+ "description, location, snmpProfile, winbox, winboxPort, ssh, sshPort, web, "
|
||||
+ "webPort, webVerze, telnet, telnetPort, sms, smsPort, smsVerze) "
|
||||
+ "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
return insertAndGetId(sql,
|
||||
node.getName(), node.getIp(), node.getX(), node.getY(),
|
||||
node.getType(), node.getSiteId(), node.getIcon(), node.isPing(),
|
||||
node.getUser(), node.getPassword(), node.getDescription(),
|
||||
node.getLocation(), node.getSnmpProfile(),
|
||||
node.isWinbox(), node.getWinboxPort(),
|
||||
node.isSsh(), node.getSshPort(),
|
||||
node.isWeb(), node.getWebPort(), node.getWebVerze(),
|
||||
node.isTelnet(), node.getTelnetPort(),
|
||||
node.isSms(), node.getSmsPort(), node.getSmsVerze()
|
||||
);
|
||||
}
|
||||
|
||||
public void removeNode(int id) {
|
||||
if (deleteById(TABLE, id)) {
|
||||
LogFile.printInfo("Node ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Node ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public void updatePosition(int nodeId, int x, int y) {
|
||||
try {
|
||||
executeUpdate("UPDATE " + TABLE + " SET x = ?, y = ? WHERE id = ?", x, y, nodeId);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("MySQL exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private Node mapNode(ResultSet rs) throws SQLException {
|
||||
return new Node(
|
||||
rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
rs.getInt("siteId"),
|
||||
rs.getInt("x"),
|
||||
rs.getInt("y"),
|
||||
rs.getInt("type"),
|
||||
rs.getInt("icon"),
|
||||
rs.getString("ip"),
|
||||
rs.getString("user"),
|
||||
rs.getString("password"),
|
||||
rs.getString("description"),
|
||||
rs.getString("location"),
|
||||
rs.getInt("snmpProfile"),
|
||||
Status.NA,
|
||||
rs.getBoolean("ping"),
|
||||
rs.getInt("winbox") == 1,
|
||||
rs.getString("winboxPort"),
|
||||
rs.getInt("ssh") == 1,
|
||||
rs.getString("sshPort"),
|
||||
rs.getInt("web") == 1,
|
||||
rs.getString("webPort"),
|
||||
rs.getInt("webVerze"),
|
||||
rs.getInt("telnet") == 1,
|
||||
rs.getString("telnetPort"),
|
||||
rs.getInt("sms") == 1,
|
||||
rs.getString("smsPort"),
|
||||
rs.getInt("smsVerze"),
|
||||
rs.getInt("siteLink"),
|
||||
new ProbeDao().getNodeProbe(rs.getInt("id"))
|
||||
);
|
||||
}
|
||||
|
||||
public void updateNode(Node node) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE + " SET name=?, siteId=?, type=?, x=?, y=?, ip=?, ping=?, icon=?, user=?, password=?, description=?, location=?, snmpProfile=?, winbox=?, winboxPort=?, ssh=?, sshPort=?, web=?, webPort=?, webVerze=?, telnet=?, telnetPort=?, sms=?, smsPort=?, smsVerze=?, siteLink=? WHERE id=?",
|
||||
node.getName(),
|
||||
node.getSiteId(),
|
||||
node.getType(),
|
||||
node.getX(),
|
||||
node.getY(),
|
||||
node.getIp(),
|
||||
(node.isPing() ? 1 : 0),
|
||||
node.getIcon(), // může být null
|
||||
node.getUser(),
|
||||
node.getPassword(),
|
||||
node.getDescription(), // může být null
|
||||
node.getLocation(), // může být null
|
||||
node.getSnmpProfile(), // může být null
|
||||
(node.isWinbox() ? 1 : 0), // může být null
|
||||
node.getWinboxPort(), // může být null
|
||||
(node.isSsh() ? 1 : 0), // může být null
|
||||
node.getSshPort(), // může být null
|
||||
(node.isWeb() ? 1 : 0), // může být null
|
||||
node.getWebPort(), // může být null
|
||||
node.getWebVerze(), // může být null
|
||||
(node.isTelnet() ? 1 : 0), // může být null
|
||||
node.getTelnetPort(), // může být null
|
||||
(node.isSms() ? 1 : 0), // může být null
|
||||
node.getSmsPort(), // může být null
|
||||
node.getSmsVerze(), // může být null
|
||||
node.getSiteLink(), // může být null
|
||||
node.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci uzlu: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import jnet.lib.object.DeviceType;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
|
||||
public class ObjectTypeDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "objectType";
|
||||
|
||||
public List<DeviceType> getObjectTypes() {
|
||||
String sql = "SELECT * FROM " + TABLE;
|
||||
return queryList(sql, rs -> new DeviceType(
|
||||
rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
rs.getString("image")
|
||||
));
|
||||
}
|
||||
|
||||
public int addObjectType(DeviceType ot) {
|
||||
String sql = "INSERT INTO " + TABLE + " (name, image) VALUES (?, ?)";
|
||||
return insertAndGetId(sql, ot.getName(), ot.getImgStr());
|
||||
}
|
||||
|
||||
public void deleteDeviceType(int id) {
|
||||
if (deleteById(TABLE, id)) {
|
||||
LogFile.printInfo("Device type ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Device type ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.NodeProbe;
|
||||
|
||||
|
||||
public class ProbeDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "nodeProbe";
|
||||
|
||||
public List<NodeProbe> getNodeProbe(int nodeId) {
|
||||
String sql = "SELECT * FROM " + TABLE + " WHERE node_id = ?";
|
||||
return queryList(sql, this::mapNodeProbe, nodeId);
|
||||
}
|
||||
|
||||
private NodeProbe mapNodeProbe(ResultSet rs) throws SQLException {
|
||||
return new NodeProbe(rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
rs.getString("oid"),
|
||||
rs.getInt("snmp_data_type"),
|
||||
rs.getString("conversion_type"),
|
||||
rs.getDouble("conversion_value"),
|
||||
rs.getString("conversion_expression"),
|
||||
rs.getString("unit"),
|
||||
rs.getInt("value_map_id"),
|
||||
rs.getInt("interval_time"),
|
||||
(rs.getInt("view_on_map") == 1 ? true:false)
|
||||
);
|
||||
}
|
||||
|
||||
public void removeNodeProbe(int id) {
|
||||
if (deleteById(TABLE, id)) {
|
||||
LogFile.printInfo("Node probe ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Node probe ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public void editNodeProbe(NodeProbe probe) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE + " SET name=?, oid=?, snmp_data_type=?, conversion_type=?, conversion_value=?, conversion_expression=?, value_map_id=?, unit=?, interval_time=?, view_on_map=? WHERE id=?",
|
||||
probe.getName(),
|
||||
probe.getOid(),
|
||||
probe.getDataType(),
|
||||
probe.getConversionType(),
|
||||
probe.getConversionValue(),
|
||||
probe.getConversionExpression(),
|
||||
probe.getValueMap(),
|
||||
probe.getUnit(),
|
||||
probe.getInterval(),
|
||||
(probe.isViewOnMap() ? 1:0),
|
||||
probe.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci uzlu: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public int addNodeProbe(NodeProbe probe) {
|
||||
String sql = "INSERT INTO " + TABLE + " (name, node_id, oid, snmp_data_type, conversion_type, conversion_value, conversion_expression, value_map_id, unit, interval_time, view_on_map) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
return insertAndGetId(
|
||||
sql,
|
||||
probe.getName(),
|
||||
probe.getNodeId(),
|
||||
probe.getOid(),
|
||||
probe.getDataType(),
|
||||
probe.getConversionType(),
|
||||
probe.getConversionValue(),
|
||||
probe.getConversionExpression(),
|
||||
probe.getValueMap(),
|
||||
probe.getUnit(),
|
||||
probe.getInterval(),
|
||||
(probe.isViewOnMap() ? 1 : 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeConnection;
|
||||
import jnet.lib.object.Site;
|
||||
import java.util.List;
|
||||
|
||||
public class SiteDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "site";
|
||||
|
||||
public List<Site> getSiteList() {
|
||||
String sql = "SELECT * FROM " + TABLE;
|
||||
return queryList(sql, rs -> {
|
||||
int siteId = rs.getInt("id");
|
||||
List<Node> nodes = new NodeDao().getNodesForSite(siteId);
|
||||
List<NodeConnection> connections = new ConnectionDao().getConnectionsForSite(siteId);
|
||||
return new Site(
|
||||
siteId,
|
||||
rs.getString("name"),
|
||||
rs.getBoolean("locked"),
|
||||
nodes,
|
||||
connections
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public int addSite(String name) {
|
||||
return insertAndGetId("INSERT INTO " + TABLE + " (name) VALUES (?)", name);
|
||||
}
|
||||
|
||||
public void removeSite(int id) {
|
||||
if (deleteById("site", id)) {
|
||||
LogFile.printInfo("Site ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("Site ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public void setSiteLock(boolean locked, int siteId) {
|
||||
try {
|
||||
executeUpdate("UPDATE " + TABLE + " SET locked = ? WHERE id = ?", locked, siteId);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("MySQL exception: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.lib.object.SnmpTemplate;
|
||||
import jnet.lib.object.SnmpValueMap;
|
||||
import jnet.lib.object.SnmpValueMapItem;
|
||||
|
||||
public class SnmpDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE_PROFILE = "snmpProfile";
|
||||
public static final String TABLE_TEMPLATE = "snmp_oid_template";
|
||||
public static final String TABLE_VALUE_MAP = "snmp_value_map";
|
||||
public static final String TABLE_VALUE_MAP_ITEM = "snmp_value_map_item";
|
||||
|
||||
public List<SnmpProfile> getAllProfile() {
|
||||
String sql = "SELECT * FROM " + TABLE_PROFILE;
|
||||
return queryList(sql, rs -> {
|
||||
return new SnmpProfile(
|
||||
rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
rs.getInt("version"),
|
||||
rs.getString("port"),
|
||||
rs.getString("communityRead")
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public List<SnmpTemplate> getSnmpTemplate() {
|
||||
String sql = "SELECT * FROM " + TABLE_TEMPLATE;
|
||||
return queryList(sql, rs -> {
|
||||
return new SnmpTemplate(
|
||||
rs.getInt("id"),
|
||||
rs.getInt("device_type"),
|
||||
rs.getString("name"),
|
||||
rs.getString("oid"),
|
||||
rs.getInt("snmp_data_type"),
|
||||
rs.getString("conversion_type"),
|
||||
rs.getDouble("conversion_value"),
|
||||
rs.getString("conversion_expression"),
|
||||
rs.getString("unit"),
|
||||
rs.getInt("value_map_id"),
|
||||
rs.getString("description")
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
public List<SnmpValueMap> getSnmpValueMapList() {
|
||||
String sql = "SELECT * FROM " + TABLE_VALUE_MAP;
|
||||
return queryList(sql, rs -> new SnmpValueMap(
|
||||
rs.getInt("id"),
|
||||
rs.getString("name"),
|
||||
getSnmpValueMapItem(rs.getInt("id"))
|
||||
));
|
||||
}
|
||||
|
||||
private List<SnmpValueMapItem> getSnmpValueMapItem(int id) {
|
||||
String sql = "SELECT * FROM " + TABLE_VALUE_MAP_ITEM + " WHERE map_id = ?";
|
||||
return queryList(sql, rs -> new SnmpValueMapItem(
|
||||
rs.getInt("id"),
|
||||
rs.getString("raw_value"),
|
||||
rs.getString("mapped_value")
|
||||
), id);
|
||||
}
|
||||
|
||||
public int addSnmpProfile(SnmpProfile profile) {
|
||||
String sql = "INSERT INTO " + TABLE_PROFILE + " (name, communityRead, port, version) VALUES (?, ?, ?, ?)";
|
||||
return insertAndGetId(
|
||||
sql,
|
||||
profile.getName(),
|
||||
profile.getCommunityRead(),
|
||||
profile.getPort(),
|
||||
profile.getVersion()
|
||||
);
|
||||
}
|
||||
|
||||
public void editSnmpProfile(SnmpProfile profile) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE_PROFILE + " SET name=?, communityRead=?, port=?, version=? WHERE id=?",
|
||||
profile.getName(),
|
||||
profile.getCommunityRead(),
|
||||
profile.getPort(),
|
||||
profile.getVersion(),
|
||||
profile.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci SNMP profilu: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void removeSnmpProfile(int id) {
|
||||
if (deleteById(TABLE_PROFILE, id)) {
|
||||
LogFile.printInfo("SNMP profile ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("SNMP profile ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public int addSnmpTemplate(SnmpTemplate template) {
|
||||
String sql = "INSERT INTO " + TABLE_TEMPLATE + " (name, device_type, oid, snmp_data_type, conversion_type, conversion_value, conversion_expression, value_map_id, unit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
return insertAndGetId(
|
||||
sql,
|
||||
template.getName(),
|
||||
template.getDeviceType(),
|
||||
template.getOid(),
|
||||
template.getDataType(),
|
||||
template.getConversionType(),
|
||||
template.getConversionValue(),
|
||||
template.getConversionExpression(),
|
||||
template.getValueMap(),
|
||||
template.getUnit()
|
||||
);
|
||||
}
|
||||
|
||||
public void editSnmpTemplate(SnmpTemplate template) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE_TEMPLATE + " SET name=?, device_type=?, oid=?, snmp_data_type=?, conversion_type=?, conversion_value=?, conversion_expression=?, value_map_id=?, unit=? WHERE id=?",
|
||||
template.getName(),
|
||||
template.getDataType(),
|
||||
template.getOid(),
|
||||
template.getDataType(),
|
||||
template.getConversionType(),
|
||||
template.getConversionValue(),
|
||||
template.getConversionExpression(),
|
||||
template.getValueMap(),
|
||||
template.getUnit(),
|
||||
template.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci SNMP template: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSnmpTemplate(int id) {
|
||||
if (deleteById(TABLE_TEMPLATE, id)) {
|
||||
LogFile.printInfo("SNMP template ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("SNMP template ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public int addSnmpValueMap(String name) {
|
||||
String sql = "INSERT INTO " + TABLE_VALUE_MAP + " (name) VALUES (?)";
|
||||
return insertAndGetId(
|
||||
sql,
|
||||
name
|
||||
);
|
||||
}
|
||||
|
||||
public int addSnmpValueMapItem(int map_id, String raw_value, String mapedValue) {
|
||||
String sql = "INSERT INTO " + TABLE_VALUE_MAP_ITEM + " (map_id, raw_value, mapped_value) VALUES (?, ?, ?)";
|
||||
return insertAndGetId(
|
||||
sql,
|
||||
map_id,
|
||||
raw_value,
|
||||
mapedValue
|
||||
);
|
||||
}
|
||||
|
||||
public void deleteSnmpValueMap(int id) {
|
||||
if (deleteById(TABLE_VALUE_MAP, id)) {
|
||||
LogFile.printInfo("SNMP Value Map ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("SNMP Value Map ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public void editSnmpValueMap(SnmpValueMap valueMap) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE_VALUE_MAP + " SET name=? WHERE id=?",
|
||||
valueMap.getName(),
|
||||
valueMap.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci SNMP Value Map: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteSnmpValueMapItem(int id) {
|
||||
if (deleteById(TABLE_VALUE_MAP_ITEM, id)) {
|
||||
LogFile.printInfo("SNMP Value Map Item ID " + id + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("SNMP Value Map Item ID " + id + " not removed from database");
|
||||
}
|
||||
}
|
||||
|
||||
public void editSnmpValueMapItem(int map_id, String raw_value, String mapedValue) {
|
||||
try {
|
||||
executeUpdate(
|
||||
"UPDATE " + TABLE_VALUE_MAP_ITEM + " SET map_id=?, raw_value=?, mapped_value=? WHERE id=?",
|
||||
raw_value,
|
||||
mapedValue,
|
||||
map_id // poslední parametr pro WHERE
|
||||
);
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci SNMP Value Map: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
package jnet.server.dao;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import jnet.lib.PasswordHashing;
|
||||
import jnet.lib.object.User;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
|
||||
public class UserDao extends AbstractDao {
|
||||
|
||||
public static final String TABLE = "users";
|
||||
|
||||
public boolean verifyUser(String username, String plainPassword) {
|
||||
String sql = "SELECT password FROM " + TABLE + " WHERE username = ?";
|
||||
String storedHash = querySingle(sql, rs -> rs.getString("password"), username);
|
||||
return storedHash != null && PasswordHashing.verify(plainPassword, storedHash);
|
||||
}
|
||||
|
||||
public User getUserInfo(String username) {
|
||||
String sql = "SELECT * FROM " + TABLE + " WHERE username = ?";
|
||||
return querySingle(sql, rs -> new User(
|
||||
rs.getInt("id"),
|
||||
rs.getString("username"),
|
||||
rs.getString("password"),
|
||||
rs.getBoolean("add_map"),
|
||||
rs.getBoolean("remove_map"),
|
||||
rs.getBoolean("edit_map"),
|
||||
rs.getBoolean("add_object"),
|
||||
rs.getBoolean("remove_object"),
|
||||
rs.getBoolean("edit_object"),
|
||||
rs.getBoolean("edit_server")
|
||||
), username);
|
||||
}
|
||||
|
||||
public List<User> getUsers() {
|
||||
String sql = "SELECT * FROM " + TABLE;
|
||||
return queryList(sql, rs -> new User(
|
||||
rs.getInt("id"),
|
||||
rs.getString("username"),
|
||||
"",
|
||||
rs.getBoolean("add_map"),
|
||||
rs.getBoolean("remove_map"),
|
||||
rs.getBoolean("edit_map"),
|
||||
rs.getBoolean("add_object"),
|
||||
rs.getBoolean("remove_object"),
|
||||
rs.getBoolean("edit_object"),
|
||||
rs.getBoolean("edit_server")
|
||||
));
|
||||
}
|
||||
|
||||
public int addUser(User user) {
|
||||
String sql = "INSERT INTO " + TABLE + " (username, password, add_map, remove_map, edit_map, "
|
||||
+ "add_object, remove_object, edit_object, edit_server) VALUES (?,?,?,?,?,?,?,?,?)";
|
||||
return insertAndGetId(sql,
|
||||
user.getUsername(), user.getPassword(),
|
||||
user.isAddMap(), user.isRemoveMap(), user.isEditMap(),
|
||||
user.isAddObject(), user.isRemoveObject(), user.isEditObject(),
|
||||
user.isEditServer()
|
||||
);
|
||||
}
|
||||
|
||||
public void editUser(User u) {
|
||||
try {
|
||||
if (u.getPassword() == null) {
|
||||
executeUpdate(
|
||||
//edit bez zmeny hesla
|
||||
"UPDATE " + TABLE + " SET username=?, add_map=?, remove_map=?, edit_map=?, add_object=?, remove_object=?, edit_object=?, edit_server=? WHERE id=?",
|
||||
u.getUsername(),
|
||||
(u.isAddMap() ? 1 : 0),
|
||||
(u.isRemoveMap() ? 1 : 0),
|
||||
(u.isEditMap() ? 1 : 0),
|
||||
(u.isAddObject() ? 1 : 0),
|
||||
(u.isRemoveObject() ? 1 : 0),
|
||||
(u.isEditObject() ? 1 : 0),
|
||||
(u.isEditServer() ? 1 : 0),
|
||||
u.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
} else {
|
||||
executeUpdate(
|
||||
// edit se zmenou hesla
|
||||
"UPDATE " + TABLE + " SET username=?, password=?, add_map=?, remove_map=?, edit_map=?, add_object=?, remove_object=?, edit_object=?, edit_server=? WHERE id=?",
|
||||
u.getUsername(),
|
||||
u.getPassword(),
|
||||
(u.isAddMap() ? 1 : 0),
|
||||
(u.isRemoveMap() ? 1 : 0),
|
||||
(u.isEditMap() ? 1 : 0),
|
||||
(u.isAddObject() ? 1 : 0),
|
||||
(u.isRemoveObject() ? 1 : 0),
|
||||
(u.isEditObject() ? 1 : 0),
|
||||
(u.isEditServer() ? 1 : 0),
|
||||
u.getId() // poslední parametr pro WHERE
|
||||
);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
LogFile.printErr("Chyba při aktualizaci uzlu: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteUser(int userId) {
|
||||
if (deleteById(TABLE, userId)) {
|
||||
LogFile.printInfo("User ID " + userId + " removed from database");
|
||||
} else {
|
||||
LogFile.printErr("User ID " + userId + " not removed from database");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import jnet.lib.Message;
|
||||
|
||||
public class MessageRegister {
|
||||
|
||||
private final Map<Integer, Register> register = new HashMap<>();
|
||||
|
||||
// Konstruktor - při vytvoření registru se sám naplní
|
||||
public MessageRegister() {
|
||||
register.put(Message.CLIENT_TYPE, new RegisterClientVersion());
|
||||
register.put(Message.AUTH_DATA, new RegisterClientAuth());
|
||||
register.put(Message.SITE_ADD, new RegisterSiteAdd());
|
||||
register.put(Message.NODE_ICON_NEW, new RegisterNodeIconNew());
|
||||
register.put(Message.USER_ADD, new RegisterUserAdd());
|
||||
register.put(Message.SITE_DELETE, new RegisterSideDelete());
|
||||
register.put(Message.NODE_POSITION_CHANGE, new RegisterNodePositionChange());
|
||||
register.put(Message.NODE_ADD, new RegisterNodeAdd());
|
||||
register.put(Message.SITE_SET_LOCK, new RegisterSiteSetLock());
|
||||
register.put(Message.NODE_DELETE, new RegisterNodeDelete());
|
||||
register.put(Message.NODE_CHANGE, new RegisterNodeChange());
|
||||
register.put(Message.SNMP_TEST, new RegisterSnmpTest());
|
||||
register.put(Message.SERVER_RESTART, new RegisterServerRestart());
|
||||
register.put(Message.SERVER_UPTIME, new RegisterServerUptime());
|
||||
register.put(Message.USER_EDIT, new RegisterUserEdit());
|
||||
register.put(Message.NODE_SNMP_INFO, new RegisterSnmpNodeInfo());
|
||||
register.put(Message.NODE_SNMP_INTERFACE, new RegisterSnmpNodeInterface());
|
||||
register.put(Message.NODE_MOVE_TO_SITE, new RegisterNodeMoveToSite());
|
||||
register.put(Message.NODE_CONNECTION_NEW, new RegisterNodeConnectionNew());
|
||||
register.put(Message.NODE_CONNECTION_EDIT, new RegisterNodeConnectionEdit());
|
||||
register.put(Message.NODE_CONNECTION_SNMP_INTERFACE, new RegisterNodeConnectionSnmpInterface());
|
||||
register.put(Message.NODE_PROBE_NEW, new RegisterNodeProbeNew());
|
||||
register.put(Message.NODE_CONNECTION_DELETE, new RegisterNodeConnectionDelete());
|
||||
register.put(Message.SNMP_PROFILE_NEW, new RegisterSnmpProfileNew());
|
||||
register.put(Message.SNMP_PROFILE_EDIT, new RegisterSnmpProfileEdit());
|
||||
register.put(Message.SNMP_PROFILE_DELETE, new RegisterSnmpProfileDelete());
|
||||
register.put(Message.NODE_PROBE_EDIT, new RegisterNodeProbeEdit());
|
||||
register.put(Message.NODE_PROBE_DELETE, new RegisterNodeProbeDelete());
|
||||
register.put(Message.SNMP_TEMPLATE_NEW, new RegisterSnmpTemplateNew());
|
||||
register.put(Message.SNMP_TEMPLATE_EDIT, new RegisterSnmpTemplateEdit());
|
||||
register.put(Message.SNMP_TEMPLATE_DELETE, new RegisterSnmpTemplateDelete());
|
||||
register.put(Message.DEVICE_TYPE_DELETE, new RegisterDeviceTypeDelete());
|
||||
register.put(Message.USER_DELETE, new RegisterUserDelete());
|
||||
register.put(Message.USER_PING_START, new RegisterUserPingStart());
|
||||
register.put(Message.USER_PING_STOP, new RegisterUserPingStop());
|
||||
register.put(Message.SERVER_LOG, new RegisterServerLog());
|
||||
register.put(Message.SERVER_CONFIG_EDIT, new RegisterServerEdit());
|
||||
register.put(Message.VALUE_MAP_NEW, new RegisterValueMapNew());
|
||||
register.put(Message.VALUE_MAP_EDIT, new RegisterValueMapEdit());
|
||||
register.put(Message.VALUE_MAP_DELETE, new RegisterValueMapDelete());
|
||||
|
||||
|
||||
}
|
||||
|
||||
public Register getRegister(int typ) {
|
||||
return register.get(typ);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
|
||||
|
||||
public interface Register {
|
||||
void processing(ChannelHandlerContext ctx, Message msg);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.net.InetSocketAddress;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.OnlineClients;
|
||||
import jnet.lib.object.ServerConfig;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterClientAuth implements Register {
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
String[] userData = (String[]) msg.getMsg();
|
||||
String username = userData[0];
|
||||
String password = userData[1];
|
||||
|
||||
InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
|
||||
String ip = remoteAddress.getAddress().getHostAddress();
|
||||
int port = remoteAddress.getPort(); // 54321
|
||||
|
||||
int platform = Integer.parseInt(userData[2]);
|
||||
|
||||
if (Database.verifyUser(username, password)) {
|
||||
LogFile.printInfo("User: " + username + " logged in (" + ip + ")");
|
||||
// odeslani potvreni autorizace
|
||||
ctx.writeAndFlush(new Message(Message.AUTH_OK, null));
|
||||
// odeslat informace o prihlasenem uzivateli, opravneni atd
|
||||
ctx.writeAndFlush(new Message(Message.USER_INFO, Database.getUserInfo(username)));
|
||||
// pridani uzivatele mezi pripojene kanaly
|
||||
ServerHandler.addChannel(ctx);
|
||||
// pridat do seznamu klientu
|
||||
Server.onlineClients.add(new OnlineClients(
|
||||
String.valueOf(ctx.channel().id()),
|
||||
username, // username
|
||||
remoteAddress.getAddress().getHostName(), // ip adresa
|
||||
String.valueOf(port), // port
|
||||
platform));
|
||||
// odeslat vsem nový seznam pripojenych klientu
|
||||
ServerHandler.sendAll(new Message(Message.ONLINE_CLIENTS, Server.onlineClients));
|
||||
// odeslat nastaveni serveru
|
||||
ctx.writeAndFlush(new Message(Message.SERVER_CONFIG, getServerConfig()));
|
||||
// odeslat seznam uzivatelu
|
||||
ctx.writeAndFlush(new Message(Message.USER_LIST, Server.users));
|
||||
// odeslat seznam icon
|
||||
ctx.writeAndFlush(new Message(Message.NODE_ICON_LIST, Server.devicType));
|
||||
// odeslat seznam udalosti
|
||||
ctx.writeAndFlush(new Message(Message.EVENT_LIST, Server.events));
|
||||
// odeslat seznam site
|
||||
ctx.writeAndFlush(new Message(Message.SITE_LIST, Server.site));
|
||||
// odeslat seznam snmp profilu
|
||||
ctx.writeAndFlush(new Message(Message.SNMP_PROFILE_LIST, Server.snmpProfile));
|
||||
// odeslat seznam snmp sablon
|
||||
ctx.writeAndFlush(new Message(Message.SNMP_TEMPLATE_LIST, Server.snmpTemplate));
|
||||
// odeslat seznam snmp value map
|
||||
ctx.writeAndFlush(new Message(Message.SNMP_TEMPLATE_VALUE_MAP_LIST, Server.snmpValueMap));
|
||||
|
||||
} else {
|
||||
LogFile.printErr("User:" + username + " has not been logged in - Incorrect user data (" + ip + ")");
|
||||
// odeslání selhani autorizace
|
||||
ctx.writeAndFlush(new Message(Message.AUTH_FAIL, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private ServerConfig getServerConfig() {
|
||||
ServerConfig sc = new ServerConfig(
|
||||
Server.config.getInt("ping_repeat"),
|
||||
Server.config.getInt("ping_attempt"),
|
||||
Server.config.getInt("ping_timeout"),
|
||||
Server.config.getInt("instability_attempt"),
|
||||
Server.config.getInt("instability_limit"),
|
||||
Server.config.getInt("traffic_interval"),
|
||||
Server.config.getInt("traffic_batch_interval"),
|
||||
Server.config.getInt("probe_batch_interval"),
|
||||
Server.config.getBoolean("debug"));
|
||||
return sc;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Server;
|
||||
|
||||
|
||||
class RegisterClientVersion implements Register {
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int clientVersion = (int) msg.getMsg();
|
||||
|
||||
if (clientVersion < Server.MINIMAL_CLIENT_VERSION) {
|
||||
// verze klienta je mensi nez pozadovana -> vyzadat aktualizaci klienta
|
||||
ctx.writeAndFlush(new Message(Message.CLIENT_UPDATE, null));
|
||||
} else {
|
||||
// verze klienta je ok -> vyzadat aktualizaci
|
||||
ctx.writeAndFlush(new Message(Message.AUTH_REQUEST, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterDeviceTypeDelete implements Register{
|
||||
|
||||
public RegisterDeviceTypeDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int id = (int) msg.getMsg();
|
||||
|
||||
Database.deleteDeviceType(id);
|
||||
|
||||
// odebere ze seznamu
|
||||
Server.devicType.removeIf(obj -> obj.getId() == id);
|
||||
|
||||
ServerHandler.sendAll(Message.DEVICE_TYPE_DELETE_RESULT, id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.server.probe.Ping;
|
||||
|
||||
|
||||
public class RegisterNodeAdd implements Register {
|
||||
|
||||
public RegisterNodeAdd() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Node node = (Node) msg.getMsg();
|
||||
// vlozi do databaze a získa id
|
||||
int id = Database.addNode(node);
|
||||
node.setId(id);
|
||||
// vlozi do seznamu
|
||||
for (Site site : Server.site) {
|
||||
if (site.getId() == node.getSiteId()) {
|
||||
site.getNode().add(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// odesle novy node klientum
|
||||
ServerHandler.sendAll(new Message(Message.NODE_NEW, node));
|
||||
// pokud je povolen ping zaradí ke sledovani
|
||||
if (node.isPing()) {
|
||||
Ping.addOrUpdateTarget(node.getId(), node.getIp());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.List;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.server.probe.Ping;
|
||||
|
||||
public class RegisterNodeChange implements Register {
|
||||
|
||||
public RegisterNodeChange() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Node newNode = (Node) msg.getMsg();
|
||||
for (Site site : Server.site) {
|
||||
List<Node> nodes = site.getNode(); // nebo použijte rozhraní
|
||||
for (int i = 0; i < nodes.size(); i++) {
|
||||
if (nodes.get(i).getId() == newNode.getId()) {
|
||||
// nahradi node v seznamu
|
||||
nodes.set(i, newNode);
|
||||
// aktualizuje v databazi
|
||||
Database.editNode(newNode);
|
||||
// aktualizuje ping
|
||||
if (newNode.isPing()) {
|
||||
// aktualizuje
|
||||
Ping.addOrUpdateTarget(newNode.getId(), newNode.getIp());
|
||||
} else {
|
||||
// odebere target z pingu
|
||||
Ping.removeTarget(newNode.getId());
|
||||
}
|
||||
// odesle zmenu klientum
|
||||
ServerHandler.sendAll(Message.NODE_UPDATE, newNode);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.server.probe.Ping;
|
||||
|
||||
|
||||
public class RegisterNodeConnectionDelete implements Register {
|
||||
|
||||
public RegisterNodeConnectionDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int id = (int) msg.getMsg();
|
||||
|
||||
// smazani z lokalniho seznamu
|
||||
for (Site site : Server.site) {
|
||||
// odebere ze seznamu
|
||||
site.getNodeConnection().removeIf(nodeConnection -> nodeConnection.getId() == id);
|
||||
// odebere z databaze
|
||||
Database.removeNodeConnection(id);
|
||||
// smazani z traffic monitoru
|
||||
Server.trafficMonitorService.removeDevice(id);
|
||||
// odesle informaci vsem
|
||||
ServerHandler.sendAll(Message.NODE_CONNECTION_REMOVE, id);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.List;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeConnection;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterNodeConnectionEdit implements Register {
|
||||
|
||||
public RegisterNodeConnectionEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
NodeConnection nc = (NodeConnection) msg.getMsg();
|
||||
|
||||
for (Site site : Server.site) {
|
||||
List<NodeConnection> connection = site.getNodeConnection(); // nebo použijte rozhraní
|
||||
for (int i = 0; i < connection.size(); i++) {
|
||||
if (connection.get(i).getId() == nc.getId()) {
|
||||
// nahradi node v seznamu
|
||||
connection.set(i, nc);
|
||||
// aktualizuje v databazi
|
||||
Database.editNodeconnection(nc);
|
||||
// odebere traffic monitor
|
||||
Server.trafficMonitorService.removeDevice(nc.getId());
|
||||
// a pokud je zapnute cteni znovu ho prida
|
||||
if (nc.isReadTraffic()) {
|
||||
// ziska info o node
|
||||
Node node = site.getNode().stream()
|
||||
.filter(n -> n.getId() == nc.getTrafficNode())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
// ziska info o profilu
|
||||
SnmpProfile profile = Server.snmpProfile.stream()
|
||||
.filter(p -> p.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
// prida ke čtení
|
||||
Server.trafficMonitorService.addDevice(nc.getId(), node.getIp(), profile.getPort(), profile.getCommunityRead(), profile.getVersion(), nc.getTrafficIface());
|
||||
// odesle infomaci o zmene
|
||||
ServerHandler.sendAll(Message.NODE_CONNECTION_CHANGE, nc);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeConnection;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterNodeConnectionNew implements Register {
|
||||
|
||||
private Node node = null;
|
||||
|
||||
public RegisterNodeConnectionNew() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
NodeConnection nc = (NodeConnection) msg.getMsg();
|
||||
|
||||
// ulozeni do databaze
|
||||
int id = Database.addNodeConnection(nc);
|
||||
|
||||
// vlozen id
|
||||
nc.setId(id);
|
||||
|
||||
// ulozeni do mistniho seznamu
|
||||
for (Site site : Server.site) {
|
||||
if (site.getId() == nc.getSite()) {
|
||||
site.getNodeConnection().add(nc);
|
||||
|
||||
// je-li zapnuto cteni trafficu
|
||||
if (nc.isReadTraffic()) {
|
||||
node = site.getNode().stream()
|
||||
.filter(n -> n.getId() == nc.getTrafficNode())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// odeslani zmeny site
|
||||
ServerHandler.sendAll(Message.NODE_CONNECTION_ADD, nc);
|
||||
|
||||
// je-li zapnuto cteni trafficu
|
||||
if (nc.isReadTraffic() && node != null) {
|
||||
SnmpProfile profile = Server.snmpProfile.stream()
|
||||
.filter(p -> p.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
Server.trafficMonitorService.addDevice(nc.getId(), node.getIp(), profile.getPort(), profile.getCommunityRead(), profile.getVersion(), nc.getTrafficIface());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Interface;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.snmp.SNMPInterfaceScanner;
|
||||
|
||||
|
||||
public class RegisterNodeConnectionSnmpInterface implements Register {
|
||||
|
||||
public RegisterNodeConnectionSnmpInterface() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
try {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
String frame = (String) data[0];
|
||||
Node node = (Node) data[1];
|
||||
// zjistit snmp profile
|
||||
SnmpProfile snmpProfile = Server.snmpProfile.stream()
|
||||
.filter(profile -> profile.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (snmpProfile != null) {
|
||||
// odeslat pozadavek
|
||||
SNMPInterfaceScanner scanner = new SNMPInterfaceScanner(
|
||||
node.getIp(),
|
||||
snmpProfile.getPort(),
|
||||
snmpProfile.getCommunityRead(),
|
||||
snmpProfile.getVersion()
|
||||
);
|
||||
|
||||
List<Interface> ifaces = scanner.scanInterfaces();
|
||||
Object[] result = {frame, ifaces};
|
||||
ctx.writeAndFlush(new Message(Message.NODE_CONNECTION_SNMP_INTERFACE_RESULT, result));
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
LogFile.printErr("SNMP interface scan error: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.util.Objects;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.server.probe.Ping;
|
||||
|
||||
|
||||
public class RegisterNodeDelete implements Register{
|
||||
|
||||
public RegisterNodeDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int nodeId = (int) msg.getMsg();
|
||||
for (Site site : Server.site) {
|
||||
// odebere ze seznamu
|
||||
site.getNode().removeIf(node -> node.getId() == nodeId);
|
||||
// odebere z databaze
|
||||
Database.removeNode(nodeId);
|
||||
// odebere target z pingu
|
||||
Ping.removeTarget(nodeId);
|
||||
// odesle informaci vsem
|
||||
ServerHandler.sendAll(Message.NODE_REMOVE, nodeId);
|
||||
break;
|
||||
}
|
||||
// smazat z eventu
|
||||
Server.events.removeIf(event -> Objects.equals(event.getNode(), nodeId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.DeviceType;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterNodeIconNew implements Register {
|
||||
|
||||
public RegisterNodeIconNew() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
DeviceType not = (DeviceType) msg.getMsg();
|
||||
// ulozit do databaze
|
||||
int id = Database.addObjectType(not);
|
||||
// pridat do seznamu
|
||||
not.setId(id);
|
||||
Server.devicType.add(not);
|
||||
// odeslat vsem novy seznam
|
||||
ServerHandler.sendAll(new Message(Message.NODE_ICON_LIST, Server.devicType));
|
||||
// klientovi odeslat pokyn k aktualizaci tabulky
|
||||
ctx.writeAndFlush(new Message(Message.NODE_ICON_REFRESH, null));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterNodeMoveToSite implements Register {
|
||||
|
||||
public RegisterNodeMoveToSite() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int[] data = (int[]) msg.getMsg();
|
||||
int nodeId = data[0];
|
||||
int targetSiteId = data[1];
|
||||
int newX = data[2];
|
||||
int newY = data[3];
|
||||
Node node = new Node();
|
||||
|
||||
for (Site site : Server.site) { // Server.site je List<Site>
|
||||
for (Node n : site.getNode()) {
|
||||
if (n.getId() == nodeId) {
|
||||
// najdeme node v puvodni mape a ulozime si ho
|
||||
node = n;
|
||||
// odebereme z puvodni site
|
||||
site.getNode().remove(n);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// nastavime nové hodnoty x a y
|
||||
node.setX(newX);
|
||||
node.setY(newY);
|
||||
node.setSiteId(targetSiteId);
|
||||
|
||||
// najdeme cilovou site a vlozime do ni node
|
||||
for (Site site : Server.site) { // Server.site je List<Site>
|
||||
if (site.getId() == targetSiteId) {
|
||||
site.getNode().add(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// smazat connection
|
||||
Database.deteleConnectionAfterNodeMove(node.getId());
|
||||
|
||||
// upravime v databazi
|
||||
Database.editNode(node);
|
||||
|
||||
// odesleme delete z puvodni site klientum
|
||||
ServerHandler.sendAll(Message.NODE_REMOVE, nodeId);
|
||||
|
||||
// odesleme klientum node do nove site
|
||||
ServerHandler.sendAll(Message.NODE_NEW, node);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterNodePositionChange implements Register {
|
||||
|
||||
public RegisterNodePositionChange() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int[] data = (int[]) msg.getMsg();
|
||||
int nodeId = data[0];
|
||||
int x = data[1];
|
||||
int y = data[2];
|
||||
|
||||
// najit node v seznamu a upravit mu pozici
|
||||
boolean changed = false;
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
if (node.getId() == nodeId) {
|
||||
// zmenit v seznamu
|
||||
node.setX(x);
|
||||
node.setY(y);
|
||||
// zmenit v databazi
|
||||
Database.nodeUpdatePosition(nodeId, x, y);
|
||||
// odeslat novou pozici klientum
|
||||
ServerHandler.sendAll(new Message(Message.NODE_CHANGE_POSITION, msg.getMsg()));
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterNodeProbeDelete implements Register {
|
||||
|
||||
public RegisterNodeProbeDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] obj = (Object[]) msg.getMsg();
|
||||
int probeId = (int) obj[0];
|
||||
String frame = (String) obj[1];
|
||||
|
||||
// odebere ze seznamu
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
node.getProbe().removeIf(probe -> probe.getId() == probeId);
|
||||
}
|
||||
}
|
||||
|
||||
// odebere z databaze
|
||||
Database.removeNodeProbe(probeId);
|
||||
|
||||
// odebere ze sledovani
|
||||
Server.snmpProbeManager.removeTask(probeId);
|
||||
|
||||
// odesle informaci vsem
|
||||
Object[] reply = {probeId, frame};
|
||||
ServerHandler.sendAll(Message.NODE_PROBE_DELETE_RESULT, reply);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeProbe;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.server.probe.snmp.MonitorConfig;
|
||||
|
||||
|
||||
public class RegisterNodeProbeEdit implements Register {
|
||||
|
||||
public RegisterNodeProbeEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] obj = (Object[]) msg.getMsg();
|
||||
NodeProbe probe = (NodeProbe) obj[0];
|
||||
String frame = (String) obj[1];
|
||||
|
||||
// upravit v lokalnim seznamu
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
for (int i = 0; i < node.getProbe().size(); i++) {
|
||||
if (node.getProbe().get(i).getId() == probe.getId()) {
|
||||
node.getProbe().set(i, probe);
|
||||
// upravit monitor
|
||||
runMonitor(node, probe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// uprvait v databazi
|
||||
Database.editNodeProbe(probe);
|
||||
|
||||
// odeslat zmenu klientum
|
||||
Object[] reply = {probe, frame};
|
||||
ServerHandler.sendAll(Message.NODE_PROBE_EDIT_RESULT, reply);
|
||||
}
|
||||
|
||||
private void runMonitor(Node node, NodeProbe probe) {
|
||||
SnmpProfile profile = Server.snmpProfile.stream()
|
||||
.filter(p -> p.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
// nejdriv odebrat
|
||||
Server.snmpProbeManager.removeTask(probe.getId());
|
||||
// pak znovu přidat
|
||||
Server.snmpProbeManager.addTask(new MonitorConfig(
|
||||
probe.getId(),
|
||||
node.getIp(),
|
||||
profile.getCommunityRead(),
|
||||
profile.getPort(),
|
||||
profile.getVersion(),
|
||||
probe.getOid(),
|
||||
probe.getInterval()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeProbe;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.server.probe.snmp.MonitorConfig;
|
||||
|
||||
public class RegisterNodeProbeNew implements Register {
|
||||
|
||||
public RegisterNodeProbeNew() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] obj = (Object[]) msg.getMsg();
|
||||
NodeProbe probe = (NodeProbe) obj[0];
|
||||
String frame = (String) obj[1];
|
||||
|
||||
// vlozeni do databaze
|
||||
int id = Database.addNodeProbe(probe);
|
||||
probe.setId(id);
|
||||
|
||||
// vlozeni do lokalniho seznamu
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
if (node.getId() == probe.getNodeId()) {
|
||||
node.getProbe().add(probe);
|
||||
// spustit snmp dotazovani
|
||||
runMonitor(node, probe);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// odeslat zmenu klientum
|
||||
Object[] reply = {probe, frame};
|
||||
ServerHandler.sendAll(Message.NODE_PROBE_NEW_RESULT, reply);
|
||||
}
|
||||
|
||||
private void runMonitor(Node node, NodeProbe probe) {
|
||||
SnmpProfile profile = Server.snmpProfile.stream()
|
||||
.filter(p -> p.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
Server.snmpProbeManager.addTask(new MonitorConfig(
|
||||
probe.getId(),
|
||||
node.getIp(),
|
||||
profile.getCommunityRead(),
|
||||
profile.getPort(),
|
||||
profile.getVersion(),
|
||||
probe.getOid(),
|
||||
probe.getInterval()
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.ApacheConfig;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.ServerConfig;
|
||||
import jnet.server.Server;
|
||||
import org.apache.commons.configuration2.ex.ConfigurationException;
|
||||
|
||||
public class RegisterServerEdit implements Register {
|
||||
|
||||
public RegisterServerEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
ServerConfig sc = (ServerConfig) msg.getMsg();
|
||||
|
||||
Server.config.setProperty("debug", sc.isDebug());
|
||||
Server.config.setProperty("ping_repeat", sc.getPingRepeat());
|
||||
Server.config.setProperty("ping_timeout", sc.getPingTimeout());
|
||||
Server.config.setProperty("ping_attempt", sc.getPingAttempt());
|
||||
Server.config.setProperty("instability_attempt", sc.getInstabilityAttempt());
|
||||
Server.config.setProperty("instability_limit", sc.getInstabilityLimit());
|
||||
Server.config.setProperty("traffic_interval", sc.getTrafficInterval());
|
||||
Server.config.setProperty("traffic_batch_interval", sc.getTrafficBatchInterval());
|
||||
Server.config.setProperty("probe_batch_interval", sc.getProbeBatchInterval());
|
||||
|
||||
try {
|
||||
ApacheConfig.saveProperties(Server.config);
|
||||
LogFile.printInfo("Nastavení uloženo.");
|
||||
} catch (ConfigurationException ex) {
|
||||
LogFile.printErr("Nastavení nebylo uloženo. " + ex.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterServerLog implements Register{
|
||||
|
||||
public RegisterServerLog() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
try {
|
||||
// Načtení všech řádků souboru do List<String>
|
||||
List<String> lines = Files.readAllLines(Paths.get("log"));
|
||||
// Převod na String[]
|
||||
String[] logRecords = lines.toArray(new String[0]);
|
||||
|
||||
ctx.writeAndFlush(new Message(Message.SERVER_LOG_RESULT, logRecords));
|
||||
|
||||
} catch (IOException e) {
|
||||
// Ošetření chyby – např. logování nebo zaslání chybové zprávy
|
||||
e.printStackTrace();
|
||||
// případně ctx.writeAndFlush(...)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Server;
|
||||
|
||||
public class RegisterServerRestart implements Register {
|
||||
|
||||
public RegisterServerRestart() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
restartService();
|
||||
}
|
||||
|
||||
public static void restartService() {
|
||||
try {
|
||||
ProcessBuilder builder = new ProcessBuilder(
|
||||
"sudo", "systemctl", "restart", "jnetserver.service"
|
||||
);
|
||||
builder.inheritIO(); // pro viditelnost výstupu v konzoli
|
||||
builder.start();
|
||||
|
||||
// Po zavolání restartu službu ukončíme
|
||||
// systemd službu automaticky znovu spustí
|
||||
//System.exit(0);
|
||||
|
||||
} catch (IOException e) {
|
||||
LogFile.printErr("Restart error: " +e.getLocalizedMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void restartServer() {
|
||||
try {
|
||||
// Získání cesty k aktuálnímu JAR souboru
|
||||
String jarPath = new File(Server.class.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI())
|
||||
.getAbsolutePath();
|
||||
|
||||
// Získání původních argumentů (pokud byly použity)
|
||||
String[] originalArgs = System.getProperty("sun.java.command").split(" ");
|
||||
|
||||
// Sestavení příkazu
|
||||
List<String> command = new ArrayList<>();
|
||||
command.add(System.getProperty("java.home") + File.separator + "bin" + File.separator + "java");
|
||||
command.add("-jar");
|
||||
command.add(jarPath);
|
||||
command.addAll(Arrays.asList(originalArgs)); // přidání původních argumentů
|
||||
|
||||
// Spuštění nového procesu
|
||||
ProcessBuilder processBuilder = new ProcessBuilder(command);
|
||||
processBuilder.inheritIO(); // převzetí stdout/stderr
|
||||
processBuilder.start();
|
||||
|
||||
// Ukončení aktuálního procesu
|
||||
System.exit(0);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// Chyba - nelze restartovat
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import jnet.lib.Message;
|
||||
|
||||
|
||||
public class RegisterServerUptime implements Register {
|
||||
|
||||
public RegisterServerUptime() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
long uptime = ManagementFactory.getRuntimeMXBean().getUptime();
|
||||
ctx.writeAndFlush(new Message(Message.SERVER_UPTIME_RESULT, uptime));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterSideDelete implements Register {
|
||||
|
||||
public RegisterSideDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int id = (int) msg.getMsg();
|
||||
// odebere ze seznamu
|
||||
Server.site.removeIf(site -> site.getId() == id);
|
||||
// odebere z databaze
|
||||
Database.removeSite(id);
|
||||
// odessle novy seznam map
|
||||
ServerHandler.sendAll(new Message(Message.SITE_LIST, Server.site));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterSiteAdd implements Register {
|
||||
|
||||
public RegisterSiteAdd() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
String name = (String) msg.getMsg();
|
||||
// vlozeni do databaze a ziskani id vlozeneho radku
|
||||
int siteId = Database.addSite(name);
|
||||
// priprava Site objektu
|
||||
Site site= new Site(siteId, name);
|
||||
// pridání do seznamu na serveru
|
||||
Server.site.add(site);
|
||||
// odeslani nove mapy vsem klientum
|
||||
ServerHandler.sendAll(new Message(Message.SITE_NEW, site));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterSiteSetLock implements Register{
|
||||
|
||||
public RegisterSiteSetLock() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
|
||||
for (Site site : Server.site) {
|
||||
if (site.getId() == (int) data[0]) {
|
||||
// zamknout v lokalnim seznamu
|
||||
site.setLock((boolean) data[1]);
|
||||
// zamknout v databazi
|
||||
Database.setSiteLock((boolean) data[1], (int) data[0]);
|
||||
// odeslat informaci klientum
|
||||
ServerHandler.sendAll(new Message(Message.SITE_LOCK, data));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.io.IOException;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.DeviceInfo;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.snmp.SNMPDeviceInfo;
|
||||
|
||||
public class RegisterSnmpNodeInfo implements Register {
|
||||
|
||||
public RegisterSnmpNodeInfo() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
String frame = (String) data[0];
|
||||
Node node = (Node) data[1];
|
||||
// zjistit snmp profile
|
||||
SnmpProfile snmpProfile = Server.snmpProfile.stream()
|
||||
.filter(profile -> profile.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (snmpProfile != null) {
|
||||
// odeslat pozadavek
|
||||
SNMPDeviceInfo snmp = new SNMPDeviceInfo(node.getIp(), snmpProfile.getPort(), snmpProfile.getCommunityRead(), snmpProfile.getVersion());
|
||||
DeviceInfo info = snmp.getDeviceInfo(); // spojení se automaticky uzavře
|
||||
Object[] result = {frame, info};
|
||||
ctx.writeAndFlush(new Message(Message.NODE_SNMP_INFO_RESULT, result));
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
LogFile.printErr("SNMP info error: " + ex.getMessage());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.Interface;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.snmp.SNMPInterfaceScanner;
|
||||
|
||||
public class RegisterSnmpNodeInterface implements Register {
|
||||
|
||||
public RegisterSnmpNodeInterface() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
String frame = (String) data[0];
|
||||
Node node = (Node) data[1];
|
||||
// zjistit snmp profile
|
||||
SnmpProfile snmpProfile = Server.snmpProfile.stream()
|
||||
.filter(profile -> profile.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if (snmpProfile != null) {
|
||||
// odeslat pozadavek
|
||||
SNMPInterfaceScanner scanner = new SNMPInterfaceScanner(
|
||||
node.getIp(),
|
||||
snmpProfile.getPort(),
|
||||
snmpProfile.getCommunityRead(),
|
||||
snmpProfile.getVersion()
|
||||
);
|
||||
|
||||
List<Interface> ifaces = scanner.scanInterfaces();
|
||||
Object[] result = {frame, ifaces};
|
||||
ctx.writeAndFlush(new Message(Message.NODE_SNMP_INTERFACE_RESULT, result));
|
||||
}
|
||||
|
||||
} catch (IOException ex) {
|
||||
LogFile.printErr("SNMP interface scan error: " + ex.getMessage());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterSnmpProfileDelete implements Register {
|
||||
|
||||
public RegisterSnmpProfileDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int profileId = (int) msg.getMsg();
|
||||
|
||||
// odebere ze seznamu
|
||||
Server.snmpProfile.removeIf(snmpProfile -> snmpProfile.getId() == profileId);
|
||||
// odebere z databaze
|
||||
Database.removeSnmpProfile(profileId);
|
||||
// odesle informaci vsem
|
||||
ServerHandler.sendAll(Message.SNMP_PROFILE_DELETE_RESULT, profileId);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterSnmpProfileEdit implements Register {
|
||||
|
||||
public RegisterSnmpProfileEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
SnmpProfile profile = (SnmpProfile) msg.getMsg();
|
||||
|
||||
// upravit v databazi
|
||||
Database.editSnmpProfile(profile);
|
||||
|
||||
// upravit v lokalnim seznamu
|
||||
for (int i = 0; i < Server.snmpProfile.size(); i++) {
|
||||
if (Server.snmpProfile.get(i).getId() == profile.getId()) {
|
||||
// nahradi node v seznamu
|
||||
Server.snmpProfile.set(i, profile);
|
||||
break;
|
||||
}
|
||||
}
|
||||
System.out.println("jnet.server.message.RegisterSnmpProfileEdit.processing()");
|
||||
ServerHandler.sendAll(Message.SNMP_PROFILE_EDIT_RESULT, profile);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterSnmpProfileNew implements Register {
|
||||
|
||||
public RegisterSnmpProfileNew() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
SnmpProfile profile = (SnmpProfile) msg.getMsg();
|
||||
|
||||
int id = Database.addSnmpProfile(profile);
|
||||
|
||||
profile.setId(id);
|
||||
|
||||
Server.snmpProfile.add(profile);
|
||||
|
||||
ServerHandler.sendAll(Message.SNMP_PROFILE_NEW_RESULT, profile);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterSnmpTemplateDelete implements Register {
|
||||
|
||||
public RegisterSnmpTemplateDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int id = (int) msg.getMsg();
|
||||
|
||||
Database.deleteSnmpTemplate(id);
|
||||
|
||||
Server.snmpTemplate.removeIf(template -> template.getId() == id);
|
||||
|
||||
ServerHandler.sendAll(Message.SNMP_TEMPLATE_DELETE_RESULT, id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.SnmpTemplate;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterSnmpTemplateEdit implements Register {
|
||||
|
||||
public RegisterSnmpTemplateEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
SnmpTemplate template = (SnmpTemplate) msg.getMsg();
|
||||
|
||||
Database.editSnmpTemplate(template);
|
||||
|
||||
for (int i = 0; i < Server.snmpTemplate.size(); i++) {
|
||||
if (Server.snmpTemplate.get(i).getId() == template.getId()) {
|
||||
Server.snmpTemplate.set(i, template);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ServerHandler.sendAll(Message.SNMP_TEMPLATE_EDIT_RESULT, template);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.SnmpTemplate;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterSnmpTemplateNew implements Register {
|
||||
|
||||
public RegisterSnmpTemplateNew() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
SnmpTemplate template = (SnmpTemplate) msg.getMsg();
|
||||
|
||||
int id = Database.addSnmpTemplate(template);
|
||||
template.setId(id);
|
||||
|
||||
Server.snmpTemplate.add(template);
|
||||
|
||||
ServerHandler.sendAll(Message.SNMP_TEMPLATE_NEW_RESULT, template);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.Target;
|
||||
import org.snmp4j.TransportMapping;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.Address;
|
||||
import org.snmp4j.smi.GenericAddress;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
||||
|
||||
public class RegisterSnmpTest implements Register {
|
||||
|
||||
public RegisterSnmpTest() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
String ip = (String) data[0];
|
||||
String port = (String) data[1];
|
||||
int version = (int) data[2];
|
||||
String communityRead = (String) data[3];
|
||||
String frame = (String) data[4];
|
||||
|
||||
String result = testSnmpGet(ip, port, communityRead, ".1.3.6.1.2.1.1.1.0", version, 5*1000);
|
||||
if (result.startsWith("ERROR:")) {
|
||||
Object[] reply = {frame, false};
|
||||
ctx.writeAndFlush(new Message(Message.SNMP_TEST_RESULT, reply));
|
||||
} else {
|
||||
Object[] reply = {frame, true};
|
||||
ctx.writeAndFlush(new Message(Message.SNMP_TEST_RESULT, reply));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Otestuje SNMP GET na zadaném zařízení.
|
||||
*
|
||||
* @param ip IP adresa (např. "192.168.1.100")
|
||||
* @param community Komunitní řetězec (např. "public")
|
||||
* @param oid OID ve tvaru ".1.3.6.1.2.1.1.1.0" nebo "1.3.6.1.2.1.1.1.0"
|
||||
* @param timeoutMs Timeout v milisekundách (např. 3000)
|
||||
* @return String s hodnotou OID, nebo zpráva začínající "ERROR: " při chybě
|
||||
*/
|
||||
public static String testSnmpGet(String ip, String port, String community, String oid,
|
||||
int version, int timeoutMs) {
|
||||
try (TransportMapping<?> transport = new DefaultUdpTransportMapping();
|
||||
Snmp snmp = new Snmp(transport)) {
|
||||
transport.listen();
|
||||
|
||||
Address targetAddress = GenericAddress.parse("udp:" + ip + "/"+port);
|
||||
Target target;
|
||||
|
||||
if (version == 1 || version == 2) {
|
||||
// SNMPv1 nebo v2c
|
||||
CommunityTarget ct = new CommunityTarget();
|
||||
ct.setCommunity(new OctetString(community));
|
||||
ct.setVersion(version == 1 ? SnmpConstants.version1 : SnmpConstants.version2c);
|
||||
target = ct;
|
||||
} else if (version == 3) {
|
||||
// SNMPv3 – vyžaduje další údaje (uživatel, auth, priv)
|
||||
// Zde je potřeba předat i jméno, hesla – proto raději udělejte přetíženou verzi
|
||||
return "ERROR: Pro SNMPv3 použijte speciální funkci s parametry auth/priv.";
|
||||
} else {
|
||||
return "ERROR: Neznámá verze SNMP (povoleno 1, 2, 3)";
|
||||
}
|
||||
|
||||
target.setAddress(targetAddress);
|
||||
target.setTimeout(timeoutMs);
|
||||
target.setRetries(1);
|
||||
|
||||
PDU pdu = new PDU();
|
||||
pdu.add(new VariableBinding(new OID(oid)));
|
||||
pdu.setType(PDU.GET);
|
||||
|
||||
ResponseEvent event = snmp.send(pdu, target);
|
||||
PDU response = event.getResponse();
|
||||
|
||||
if (response == null) {
|
||||
return "ERROR: Žádná odpověď (timeout)";
|
||||
}
|
||||
VariableBinding vb = response.get(0);
|
||||
return (vb == null) ? "ERROR: Prázdná odpověď" : vb.getVariable().toString();
|
||||
|
||||
} catch (Exception e) {
|
||||
return "ERROR: " + e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.PasswordHashing;
|
||||
import jnet.lib.object.User;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterUserAdd implements Register {
|
||||
|
||||
public RegisterUserAdd() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
User u = (User) msg.getMsg();
|
||||
u.setPassword(PasswordHashing.hash(u.getPassword()));
|
||||
//pridáni do databáze a nastaveni id
|
||||
u.setId(Database.addUser(u));
|
||||
// přidání do seznamu
|
||||
Server.users.add(u);
|
||||
// odeslat klientum novy seznam uzivatelu
|
||||
ServerHandler.sendAll(new Message(Message.USER_LIST, Server.users));
|
||||
// odeslat klientovi infomraci o pridani a aktualizaci tabulky
|
||||
ctx.writeAndFlush(new Message(Message.USER_REFRESH, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterUserDelete implements Register {
|
||||
|
||||
public RegisterUserDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int userId = (int) msg.getMsg();
|
||||
|
||||
Database.deleteUser(userId);
|
||||
|
||||
Server.users.removeIf(user -> user.getId() == userId);
|
||||
|
||||
// odessle novy seznam map
|
||||
ServerHandler.sendAll(new Message(Message.USER_DELETE, userId));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.PasswordHashing;
|
||||
import jnet.lib.object.User;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterUserEdit implements Register {
|
||||
|
||||
public RegisterUserEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
User u = (User) msg.getMsg();
|
||||
// bude se editovat heslo ?
|
||||
if (u.getPassword() != null) {
|
||||
u.setPassword(PasswordHashing.hash(u.getPassword()));
|
||||
}
|
||||
// ulozeni do databaze
|
||||
Database.editUser(u);
|
||||
// aktualizace v seznamu
|
||||
for (int i = 0; i < Server.users.size(); i++) {
|
||||
if (Server.users.get(i).getId() == u.getId()) {
|
||||
// nahradi node v seznamu
|
||||
Server.users.set(i, u);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// odeslat klientum novy seznam uzivatelu
|
||||
ServerHandler.sendAll(new Message(Message.USER_LIST, Server.users));
|
||||
// odeslat klientovi infomraci o pridani a aktualizaci tabulky
|
||||
ctx.writeAndFlush(new Message(Message.USER_REFRESH, null));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.userping.PingManager;
|
||||
|
||||
public class RegisterUserPingStart implements Register {
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
if (data == null || data.length < 2) {
|
||||
ctx.writeAndFlush(new Message(Message.USER_PING_STARTED, "ERR: Missing IP or frameName"));
|
||||
return;
|
||||
}
|
||||
String ip = data[0].toString();
|
||||
String frameName = data[1].toString();
|
||||
|
||||
if (ip.trim().isEmpty() || frameName.trim().isEmpty()) {
|
||||
ctx.writeAndFlush(new Message(Message.USER_PING_STARTED, "ERR: Empty IP or frameName"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Sender pro odesílání odpovědí – každý řádek pošleme s frameName
|
||||
java.util.function.Consumer<String> sender = (line) -> {
|
||||
if (ctx.channel().isActive()) {
|
||||
ctx.writeAndFlush(new Message(Message.USER_PING_RESPONSE, new Object[]{frameName, line}));
|
||||
}
|
||||
};
|
||||
|
||||
String pingId = PingManager.startPing(ctx.channel(), ip.trim(), frameName, sender);
|
||||
ctx.writeAndFlush(new Message(Message.USER_PING_STARTED, "Ping started for " + ip + " frame " + frameName + " (ID: " + pingId + ")"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.userping.PingManager;
|
||||
|
||||
public class RegisterUserPingStop implements Register {
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
Object[] data = (Object[]) msg.getMsg();
|
||||
if (data == null || data.length < 2) {
|
||||
ctx.writeAndFlush(new Message(Message.USER_PING_STOPPED, "ERR: Missing IP or frameName"));
|
||||
return;
|
||||
}
|
||||
String ip = data[0].toString();
|
||||
String frameName = data[1].toString();
|
||||
String pingId = ip + ":" + frameName;
|
||||
|
||||
PingManager.stopPing(ctx.channel(), pingId);
|
||||
ctx.writeAndFlush(new Message(Message.USER_PING_STOPPED, "Ping stopped for " + pingId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterValueMapDelete implements Register {
|
||||
|
||||
public RegisterValueMapDelete() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
int id = (int) msg.getMsg();
|
||||
|
||||
Database.deleteSnmpValueMap(id);
|
||||
|
||||
// odebere ze seznamu
|
||||
Server.snmpValueMap.removeIf(vm -> vm.getId() == id);
|
||||
|
||||
ServerHandler.sendAll(Message.VALUE_MAP_DELETE_RESULT, id);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.SnmpValueMap;
|
||||
import jnet.lib.object.SnmpValueMapItem;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
public class RegisterValueMapEdit implements Register {
|
||||
|
||||
public RegisterValueMapEdit() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
SnmpValueMap vm = (SnmpValueMap) msg.getMsg();
|
||||
|
||||
Database.editSnmpValueMap(vm);
|
||||
|
||||
// nejprve smazat stare itemy mapovani
|
||||
SnmpValueMap oldValueMap = Server.snmpValueMap.stream()
|
||||
.filter(p -> p.getId() == vm.getId())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
for (SnmpValueMapItem oldItem : oldValueMap.getItem()) {
|
||||
Database.deleteSnmpValueMapItem(oldItem.getId());
|
||||
}
|
||||
|
||||
// vlozit nové itemy mapovani
|
||||
for (SnmpValueMapItem item : vm.getItem()) {
|
||||
int itemID = Database.addSnmpValueMapItem(vm.getId(), item.getRawValue(), item.getMappedValue());
|
||||
item.setId(itemID);
|
||||
}
|
||||
|
||||
// upravit v lokalnim seznamu
|
||||
for (int i = 0; i < Server.snmpValueMap.size(); i++) {
|
||||
if (Server.snmpValueMap.get(i).getId() == vm.getId()) {
|
||||
Server.snmpValueMap.set(i, vm);
|
||||
}
|
||||
}
|
||||
|
||||
// odeslat klientum
|
||||
ServerHandler.sendAll(Message.VALUE_MAP_EDIT_RESULT, vm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
package jnet.server.message;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import jnet.lib.Message;
|
||||
import jnet.lib.object.SnmpValueMap;
|
||||
import jnet.lib.object.SnmpValueMapItem;
|
||||
import jnet.server.Database;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
|
||||
|
||||
public class RegisterValueMapNew implements Register {
|
||||
|
||||
public RegisterValueMapNew() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processing(ChannelHandlerContext ctx, Message msg) {
|
||||
SnmpValueMap vm = (SnmpValueMap) msg.getMsg();
|
||||
|
||||
// zapsat do databaze a ulozit prirazene id
|
||||
int idValueMap = Database.addSnmpValueMap(vm.getName());
|
||||
vm.setId(idValueMap);
|
||||
|
||||
for (SnmpValueMapItem item : vm.getItem()) {
|
||||
int itemID = Database.addSnmpValueMapItem(idValueMap, item.getRawValue(), item.getMappedValue());
|
||||
item.setId(itemID);
|
||||
}
|
||||
|
||||
// pridat do lokalniho seznamu
|
||||
Server.snmpValueMap.add(vm);
|
||||
|
||||
// odeslat klientum
|
||||
ServerHandler.sendAll(Message.VALUE_MAP_NEW_RESULT, vm);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package jnet.server.networkserver;
|
||||
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import jnet.lib.LogFile;
|
||||
|
||||
public class NettyServerManager {
|
||||
|
||||
private EventLoopGroup boss;
|
||||
private EventLoopGroup worker;
|
||||
private ChannelFuture serverChannelFuture;
|
||||
|
||||
public void start(int port) {
|
||||
Thread serverThread = new Thread(() -> {
|
||||
boss = new NioEventLoopGroup(1);
|
||||
worker = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
SslContext sslCtx = SslUtil.createServerSslContext();
|
||||
ServerBootstrap b = new ServerBootstrap();
|
||||
b.group(boss, worker)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new ServerInitializer(sslCtx))
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true);
|
||||
|
||||
LogFile.printInfo("Starting Netty on port " + port);
|
||||
serverChannelFuture = b.bind(port).sync();
|
||||
|
||||
// Čeká na uzavření kanálu
|
||||
serverChannelFuture.channel().closeFuture().sync();
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
LogFile.printInfo("Netty server interrupted.");
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (Exception e) {
|
||||
LogFile.printInfo("Netty error: " + e.getMessage());
|
||||
} finally {
|
||||
stop();
|
||||
}
|
||||
}, "Netty-Server-Thread");
|
||||
|
||||
serverThread.start();
|
||||
}
|
||||
|
||||
public synchronized void stop() {
|
||||
if (boss != null && !boss.isShuttingDown()) {
|
||||
LogFile.printInfo("Shutting down Netty gracefully...");
|
||||
// Gracefully uzavře kanály, počká na dokončení probíhajících zápisů a ukončí vlákna
|
||||
boss.shutdownGracefully();
|
||||
worker.shutdownGracefully();
|
||||
LogFile.printInfo("Netty stopped.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package jnet.server.networkserver;
|
||||
|
||||
|
||||
import io.netty.bootstrap.ServerBootstrap;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
|
||||
public class SecureServer {
|
||||
public static void main(String[] args) throws Exception {
|
||||
SslContext sslCtx = SslUtil.createServerSslContext();
|
||||
|
||||
EventLoopGroup boss = new NioEventLoopGroup(1);
|
||||
EventLoopGroup worker = new NioEventLoopGroup();
|
||||
|
||||
try {
|
||||
ServerBootstrap b = new ServerBootstrap();
|
||||
b.group(boss, worker)
|
||||
.channel(NioServerSocketChannel.class)
|
||||
.childHandler(new ServerInitializer(sslCtx))
|
||||
.childOption(ChannelOption.SO_KEEPALIVE, true);
|
||||
|
||||
b.bind(8443).sync().channel().closeFuture().sync();
|
||||
} finally {
|
||||
boss.shutdownGracefully();
|
||||
worker.shutdownGracefully();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package jnet.server.networkserver;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import io.netty.channel.group.ChannelGroup;
|
||||
import io.netty.channel.group.DefaultChannelGroup;
|
||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.Message;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.message.MessageRegister;
|
||||
import jnet.server.message.Register;
|
||||
import jnet.server.userping.PingManager;
|
||||
|
||||
public class ServerHandler extends SimpleChannelInboundHandler<Object> {
|
||||
|
||||
private final MessageRegister messageRegistr = new MessageRegister();
|
||||
|
||||
private static final ChannelGroup allChannels
|
||||
= new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
|
||||
|
||||
@Override
|
||||
public void channelActive(ChannelHandlerContext ctx) {
|
||||
LogFile.printInfo("New client: " + ctx.channel().remoteAddress());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) {
|
||||
LogFile.printInfo("Client: " + ctx.channel().remoteAddress() + " disconnected");
|
||||
// odebere kanal
|
||||
allChannels.remove(ctx.channel());
|
||||
// odebere ze seznamu klientu
|
||||
Server.onlineClients.removeIf(onlineClient
|
||||
-> onlineClient.getId().equals(String.valueOf(ctx.channel().id()))
|
||||
);
|
||||
// odesle zmenu stavajicim klientum
|
||||
sendAll(new Message(Message.ONLINE_CLIENTS, Server.onlineClients));
|
||||
// Zastavíme všechny pingy pro tohoto klienta
|
||||
PingManager.stopAllPings(ctx.channel());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, Object msg) {
|
||||
|
||||
if (msg instanceof Message) {
|
||||
Message message = (Message) msg;
|
||||
LogFile.printDebug("Received message ID: " + message.getType());
|
||||
Register register = messageRegistr.getRegister(message.getType());
|
||||
if (register != null) {
|
||||
register.processing(ctx, message);
|
||||
}
|
||||
|
||||
} else {
|
||||
LogFile.printDebug("Unknown message received");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
|
||||
if (cause instanceof java.net.SocketException && cause.getMessage().contains("Connection reset")) {
|
||||
LogFile.printInfo("Client abruptly disconnected: " + ctx.channel().remoteAddress());
|
||||
} else {
|
||||
cause.printStackTrace();
|
||||
}
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
public static void addChannel(ChannelHandlerContext ctx) {
|
||||
allChannels.add(ctx.channel());
|
||||
}
|
||||
|
||||
public static ChannelGroup getAllChannels() {
|
||||
return allChannels;
|
||||
}
|
||||
|
||||
public static void sendAll(Message msq) {
|
||||
getAllChannels().writeAndFlush(msq);
|
||||
}
|
||||
|
||||
public static void sendAll(int type, Object msg) {
|
||||
getAllChannels().writeAndFlush(new Message(type, msg));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package jnet.server.networkserver;
|
||||
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.handler.codec.serialization.ClassResolvers;
|
||||
import io.netty.handler.codec.serialization.ObjectDecoder;
|
||||
import io.netty.handler.codec.serialization.ObjectEncoder;
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
|
||||
public class ServerInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
private final SslContext sslCtx;
|
||||
|
||||
public ServerInitializer(SslContext sslCtx) {
|
||||
this.sslCtx = sslCtx;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel ch) {
|
||||
ch.pipeline()
|
||||
.addLast("ssl", sslCtx.newHandler(ch.alloc()))
|
||||
// ObjectDecoder používá LengthFieldBasedFrameDecoder automaticky
|
||||
//.addLast("objectDecoder", new ObjectDecoder(ClassResolvers.cacheDisabled(null)))
|
||||
//.addLast("objectEncoder", new ObjectEncoder())
|
||||
.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)))
|
||||
.addLast(new ObjectEncoder())
|
||||
.addLast("handler", new ServerHandler());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package jnet.server.networkserver;
|
||||
|
||||
|
||||
import io.netty.handler.ssl.SslContext;
|
||||
import io.netty.handler.ssl.SslContextBuilder;
|
||||
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||
|
||||
public class SslUtil {
|
||||
public static SslContext createServerSslContext() throws Exception {
|
||||
SelfSignedCertificate ssc = new SelfSignedCertificate();
|
||||
return SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
package jnet.server.probe;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jnet.lib.LogFile;
|
||||
import jnet.lib.OSDetector;
|
||||
import jnet.lib.Status;
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeState;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.EventManager;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.SiteOperation;
|
||||
import jnet.server.probe.ping.MonitorEngine;
|
||||
import jnet.server.probe.ping.PingEngine;
|
||||
import jnet.server.probe.ping.RawIcmpPingEngine;
|
||||
|
||||
public class Ping {
|
||||
|
||||
private static MonitorEngine engine;
|
||||
|
||||
public static void start() {
|
||||
try {
|
||||
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
scheduler.schedule(() -> {
|
||||
run();
|
||||
}, 5, TimeUnit.SECONDS);
|
||||
scheduler.shutdown();
|
||||
scheduler.awaitTermination(10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException ex) {
|
||||
LogFile.printErr("Failed runing ping probe: " + ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void run() {
|
||||
LogFile.printInfo("Ping probe starting...");
|
||||
|
||||
// Vytvoření mapy nodeId -> IP
|
||||
Map<String, String> nodeIdToIp = new HashMap<>();
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
if (node.getType() == 1 && node.isPing()) {
|
||||
// prida jen kdyz je typ=1 (zarizeni) a ping je zapnut
|
||||
nodeIdToIp.put(String.valueOf(node.getId()), node.getIp());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
LogFile.printInfo("Loaded " + nodeIdToIp.size() + " targets.");
|
||||
|
||||
if (nodeIdToIp.isEmpty()) {
|
||||
LogFile.printInfo("No targets to monitor, exiting.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (OSDetector.isWindows()) {
|
||||
LogFile.printInfo("OS is Windows - using PingEngine (subprocess ping)");
|
||||
// OPRAVA: cyklus každých 10 sekund, timeout 2 sekundy
|
||||
engine = new PingEngine(10, 10, 2);
|
||||
} else if (OSDetector.isDebian()) {
|
||||
LogFile.printInfo("OS is Debian - using RawIcmpPingEngine");
|
||||
engine = new RawIcmpPingEngine(10, 3000, 2);
|
||||
} else {
|
||||
LogFile.printInfo("OS is undefined - ping not running");
|
||||
return;
|
||||
}
|
||||
engine.setTargets(nodeIdToIp);
|
||||
LogFile.printInfo("Targets set.");
|
||||
|
||||
// Listener pro změny stavu
|
||||
engine.addListener(event -> {
|
||||
// Sestavíme text s latencí
|
||||
String latencyText = event.up() ? event.latencyMs() + " ms" : "N/A";
|
||||
// Toto se vypíše při každé kontrole (i když není změna)
|
||||
// Detailní výpis všech informací
|
||||
// LogFile.printDebug("Listener: node=" + event.nodeId() +
|
||||
// ", ip=" + event.ip() +
|
||||
// ", up=" + event.up() +
|
||||
// ", latency=" + latencyText +
|
||||
// ", firstReport=" + event.firstReport() +
|
||||
// ", stateChanged=" + event.stateChanged());
|
||||
//
|
||||
NodeState nodeState = null;
|
||||
if (event.firstReport()) {
|
||||
if (event.up()) {
|
||||
nodeState = new NodeState(Integer.parseInt(event.nodeId()), Status.OK);
|
||||
} else {
|
||||
EventManager.insertOfflineEvent(Integer.parseInt(event.nodeId()));
|
||||
nodeState = new NodeState(Integer.parseInt(event.nodeId()), Status.OFFLINE);
|
||||
}
|
||||
SiteOperation.updateNodeStatus(nodeState);
|
||||
} else if (event.stateChanged()) {
|
||||
LogFile.printDebug("CHANGE: " + event.describe());
|
||||
if (event.up()) {
|
||||
EventManager.endEvent(Integer.parseInt(event.nodeId()));
|
||||
nodeState = new NodeState(Integer.parseInt(event.nodeId()), Status.OK);
|
||||
} else {
|
||||
EventManager.insertOfflineEvent(Integer.parseInt(event.nodeId()));
|
||||
nodeState = new NodeState(Integer.parseInt(event.nodeId()), Status.OFFLINE);
|
||||
}
|
||||
SiteOperation.updateNodeStatus(nodeState);
|
||||
}
|
||||
});
|
||||
|
||||
LogFile.printInfo("Starting engine...");
|
||||
try {
|
||||
engine.start();
|
||||
LogFile.printInfo("Engine started successfully.");
|
||||
} catch (Exception e) {
|
||||
LogFile.printErr("Failed to start engine: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public static void addOrUpdateTarget(int nodeId, String ip) {
|
||||
engine.addOrUpdateTarget(String.valueOf(nodeId), ip);
|
||||
}
|
||||
|
||||
public static void removeTarget(int nodeId) {
|
||||
engine.removeTarget(String.valueOf(nodeId));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.ptr.IntByReference;
|
||||
|
||||
/**
|
||||
* Mapovani vybranych funkci standardni C knihovny (libc) pres JNA.
|
||||
* Umoznuje otevrit RAW ICMP socket, coz standardni java.net API neumoznuje.
|
||||
*
|
||||
* DULEZITE: otevreni SOCK_RAW socketu vyzaduje bud beh pod rootem, nebo
|
||||
* capability CAP_NET_RAW nastavenou na java binarce:
|
||||
*
|
||||
* sudo setcap cap_net_raw+ep $(readlink -f $(which java))
|
||||
*
|
||||
* (Pozor: setcap se musi nastavit na *skutecny* java binary, ne na symlink
|
||||
* spravovany update-alternatives, ktery se muze pri aktualizaci JDK zmenit -
|
||||
* pouzijte radeji plnou cestu k danemu JDK, viz README.)
|
||||
*/
|
||||
public interface CLibrary extends Library {
|
||||
|
||||
CLibrary INSTANCE = Native.load("c", CLibrary.class);
|
||||
|
||||
int socket(int domain, int type, int protocol);
|
||||
|
||||
int close(int fd);
|
||||
|
||||
int sendto(int sockfd, byte[] buf, int len, int flags, SockAddrIn destAddr, int addrlen);
|
||||
|
||||
int recvfrom(int sockfd, byte[] buf, int len, int flags, Pointer srcAddr, Pointer addrlen);
|
||||
|
||||
int setsockopt(int sockfd, int level, int optname, Timeval optval, int optlen);
|
||||
|
||||
int setsockopt(int sockfd, int level, int optname, IntByReference optval, int optlen);
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Sestaveni/parsovani ICMP paketu (RFC 792) na bajtove urovni.
|
||||
*/
|
||||
public final class IcmpPacketBuilder {
|
||||
|
||||
private static final int ICMP_ECHO_REQUEST = 8;
|
||||
private static final int ICMP_ECHO_REPLY = 0;
|
||||
|
||||
private IcmpPacketBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sestavi ICMP echo request packet (hlavicka + payload) vcetne spocitaneho checksumu.
|
||||
*/
|
||||
public static byte[] buildEchoRequest(int identifier, int sequence, byte[] payload) {
|
||||
byte[] packet = new byte[8 + payload.length];
|
||||
packet[0] = (byte) ICMP_ECHO_REQUEST;
|
||||
packet[1] = 0; // code
|
||||
packet[2] = 0; // checksum - doplnime az po spocitani
|
||||
packet[3] = 0;
|
||||
packet[4] = (byte) ((identifier >> 8) & 0xFF);
|
||||
packet[5] = (byte) (identifier & 0xFF);
|
||||
packet[6] = (byte) ((sequence >> 8) & 0xFF);
|
||||
packet[7] = (byte) (sequence & 0xFF);
|
||||
System.arraycopy(payload, 0, packet, 8, payload.length);
|
||||
|
||||
int checksum = checksum(packet);
|
||||
packet[2] = (byte) ((checksum >> 8) & 0xFF);
|
||||
packet[3] = (byte) (checksum & 0xFF);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Standardni 16-bitovy jednickovy doplnkovy soucet (one's complement checksum)
|
||||
* pouzivany ICMP i IP hlavickami.
|
||||
*/
|
||||
static int checksum(byte[] buf) {
|
||||
int sum = 0;
|
||||
int i = 0;
|
||||
int length = buf.length;
|
||||
|
||||
while (length > 1) {
|
||||
int word = ((buf[i] << 8) & 0xFF00) | (buf[i + 1] & 0xFF);
|
||||
sum += word;
|
||||
if ((sum & 0xFFFF0000) != 0) {
|
||||
sum &= 0xFFFF;
|
||||
sum += 1;
|
||||
}
|
||||
i += 2;
|
||||
length -= 2;
|
||||
}
|
||||
|
||||
if (length > 0) {
|
||||
sum += (buf[i] << 8) & 0xFF00;
|
||||
if ((sum & 0xFFFF0000) != 0) {
|
||||
sum &= 0xFFFF;
|
||||
sum += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return (~sum) & 0xFFFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Rozparsuje surova prijata data z raw socketu (obsahuji IP hlavicku + ICMP zpravu)
|
||||
* a vrati identifier/sequence z ICMP echo reply, nebo null, pokud to neni echo reply.
|
||||
*/
|
||||
public static ParsedReply parseEchoReply(byte[] buf, int length) {
|
||||
if (length < 20) return null; // min. delka IP hlavicky
|
||||
|
||||
int ihl = (buf[0] & 0x0F) * 4; // Internet Header Length v bajtech
|
||||
if (length < ihl + 8) return null;
|
||||
|
||||
int type = buf[ihl] & 0xFF;
|
||||
if (type != ICMP_ECHO_REPLY) return null;
|
||||
|
||||
int identifier = ((buf[ihl + 4] & 0xFF) << 8) | (buf[ihl + 5] & 0xFF);
|
||||
int sequence = ((buf[ihl + 6] & 0xFF) << 8) | (buf[ihl + 7] & 0xFF);
|
||||
byte[] sourceAddress = Arrays.copyOfRange(buf, 12, 16);
|
||||
|
||||
return new ParsedReply(identifier, sequence, sourceAddress);
|
||||
}
|
||||
|
||||
public record ParsedReply(int identifier, int sequence, byte[] sourceAddress) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Reprezentuje jeden monitorovany cil - IP adresu se jejim aktualnim stavem.
|
||||
* Pole jsou volatile/atomicka, protoze do nich zapisuji paralelni ping-vlakna
|
||||
* a zaroven se z nich cte pri generovani web dashboardu.
|
||||
*/
|
||||
public class IpTarget {
|
||||
|
||||
public final String nodeId; // unikátní identifikátor (primární klíč)
|
||||
public volatile String ip; // IP adresa (může se měnit, volatile pro viditelnost)
|
||||
|
||||
public volatile boolean up = false;
|
||||
public volatile boolean everChecked = false;
|
||||
public volatile long lastLatencyMs = -1;
|
||||
|
||||
public volatile LocalDateTime lastChange;
|
||||
public volatile LocalDateTime lastCheck;
|
||||
|
||||
public volatile int consecutiveFails = 0;
|
||||
public volatile int consecutiveOk = 0;
|
||||
|
||||
public IpTarget(String nodeId, String ip) {
|
||||
this.nodeId = nodeId;
|
||||
this.ip = ip;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Spolecne rozhrani pro monitorovaci engine - umoznuje mit vice implementaci
|
||||
* (subprocess ping vs. raw ICMP socket) se stejnym verejnym API, takze zbytek
|
||||
* aplikace (napr. napojeni na Netty) neni na konkretni implementaci zavisly.
|
||||
*/
|
||||
public interface MonitorEngine {
|
||||
|
||||
void addOrUpdateTarget(String nodeId, String ip);
|
||||
|
||||
void removeTarget(String nodeId);
|
||||
|
||||
void setTargets(Map<String, String> nodeIdToIp); // nodeId -> IP
|
||||
|
||||
Collection<IpTarget> getTargets();
|
||||
|
||||
void addListener(StatusListener listener);
|
||||
|
||||
void removeListener(StatusListener listener);
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jnet.lib.LogFile;
|
||||
|
||||
public class PingEngine implements MonitorEngine {
|
||||
|
||||
private final ConcurrentHashMap<String, IpTarget> targets = new ConcurrentHashMap<>();
|
||||
private final CopyOnWriteArrayList<StatusListener> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private final ExecutorService pingPool;
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
private final int cycleIntervalSeconds;
|
||||
private final int pingTimeoutSeconds;
|
||||
|
||||
private ScheduledFuture<?> cycleHandle;
|
||||
private Path watchedFile;
|
||||
private long watchedFileLastModified = -1;
|
||||
|
||||
public PingEngine(int threadPoolSize, int cycleIntervalSeconds, int pingTimeoutSeconds) {
|
||||
this.pingPool = Executors.newFixedThreadPool(threadPoolSize);
|
||||
this.cycleIntervalSeconds = cycleIntervalSeconds;
|
||||
this.pingTimeoutSeconds = pingTimeoutSeconds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOrUpdateTarget(String nodeId, String ip) {
|
||||
//LogFile.printDebug("ADD ping target (node: " + nodeId + " ip: " + ip + ")");
|
||||
targets.compute(nodeId, (k, existing) -> {
|
||||
if (existing == null) {
|
||||
return new IpTarget(nodeId, ip);
|
||||
} else {
|
||||
if (!existing.ip.equals(ip)) {
|
||||
existing.ip = ip;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTarget(String nodeId) {
|
||||
targets.remove(nodeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargets(Map<String, String> nodeIdToIp) {
|
||||
targets.keySet().retainAll(nodeIdToIp.keySet());
|
||||
for (Map.Entry<String, String> entry : nodeIdToIp.entrySet()) {
|
||||
addOrUpdateTarget(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<IpTarget> getTargets() {
|
||||
return targets.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(StatusListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(StatusListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
public void enableFileWatch(Path file) {
|
||||
this.watchedFile = file;
|
||||
reloadFromFileIfChanged();
|
||||
}
|
||||
|
||||
private void reloadFromFileIfChanged() {
|
||||
if (watchedFile == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
File f = watchedFile.toFile();
|
||||
if (!f.exists()) {
|
||||
return;
|
||||
}
|
||||
long modified = f.lastModified();
|
||||
if (modified == watchedFileLastModified) {
|
||||
return;
|
||||
}
|
||||
watchedFileLastModified = modified;
|
||||
|
||||
Set<String> seen = new HashSet<>();
|
||||
List<String> lines = Files.readAllLines(watchedFile);
|
||||
for (String raw : lines) {
|
||||
String line = raw.trim();
|
||||
if (line.isEmpty() || line.startsWith("#")) {
|
||||
continue;
|
||||
}
|
||||
String[] parts = line.split(",", 2);
|
||||
String nodeId = parts[0].trim();
|
||||
String ip = parts.length > 1 ? parts[1].trim() : nodeId;
|
||||
if (nodeId.isEmpty() || ip.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
seen.add(nodeId);
|
||||
addOrUpdateTarget(nodeId, ip);
|
||||
}
|
||||
targets.keySet().retainAll(seen);
|
||||
} catch (IOException e) {
|
||||
System.err.println("Chyba při načítání " + watchedFile + ": " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
cycleHandle = scheduler.scheduleAtFixedRate(
|
||||
this::runCycle, 0, cycleIntervalSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (cycleHandle != null) {
|
||||
cycleHandle.cancel(true);
|
||||
}
|
||||
scheduler.shutdownNow();
|
||||
pingPool.shutdownNow();
|
||||
}
|
||||
|
||||
private void runCycle() {
|
||||
reloadFromFileIfChanged();
|
||||
|
||||
for (IpTarget target : targets.values()) {
|
||||
CompletableFuture
|
||||
.supplyAsync(() -> PingUtil.ping(target.ip, pingTimeoutSeconds), pingPool)
|
||||
.thenAccept(latencyMs -> handleResult(target, latencyMs))
|
||||
.exceptionally(ex -> {
|
||||
System.err.println("Chyba při pingu " + target.ip + ": " + ex.getMessage());
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== OPRAVENÁ METODA ====================
|
||||
private void handleResult(IpTarget target, long latencyMs) {
|
||||
boolean nowUp = latencyMs >= 0;
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
boolean everCheckedBefore = target.everChecked;
|
||||
|
||||
// ULOŽÍME STARÝ STAV PŘED PŘEPSÁNÍM
|
||||
boolean previouslyReportedUp = target.up;
|
||||
|
||||
target.up = nowUp;
|
||||
target.lastLatencyMs = nowUp ? latencyMs : -1;
|
||||
target.lastCheck = now;
|
||||
target.everChecked = true;
|
||||
|
||||
if (nowUp) {
|
||||
target.consecutiveOk++;
|
||||
target.consecutiveFails = 0;
|
||||
} else {
|
||||
target.consecutiveFails++;
|
||||
target.consecutiveOk = 0;
|
||||
}
|
||||
|
||||
// POROVNÁVÁME S ULOŽENÝM STARÝM STAVEM
|
||||
boolean stateChanged = everCheckedBefore && (nowUp != previouslyReportedUp);
|
||||
if (stateChanged) {
|
||||
target.lastChange = now;
|
||||
}
|
||||
|
||||
boolean firstReport = !everCheckedBefore;
|
||||
|
||||
StatusEvent event = new StatusEvent(
|
||||
target.nodeId,
|
||||
target.ip,
|
||||
nowUp,
|
||||
target.lastLatencyMs,
|
||||
stateChanged,
|
||||
firstReport,
|
||||
now
|
||||
);
|
||||
|
||||
for (StatusListener listener : listeners) {
|
||||
listener.onUpdate(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Provadi ICMP ping pomoci systemoveho prikazu "ping".
|
||||
*
|
||||
* Proc systemovy prikaz a ne InetAddress.isReachable()?
|
||||
* - isReachable() potrebuje bezet pod rootem, aby pouzil skutecne ICMP echo,
|
||||
* jinak casto padne zpet na TCP echo (port 7), coz na vetsine cilu neprojde.
|
||||
* - Systemovy binarni "ping" na Linuxu ma nastaveny setuid bit, takze funguje
|
||||
* spolehlive i pod beznym uzivatelem.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Provádí ICMP ping pomocí systemového příkazu "ping".
|
||||
* Detekuje OS a používá správnou syntaxi (Windows vs. Linux).
|
||||
*/
|
||||
public class PingUtil {
|
||||
|
||||
// Regex pro Linux: time=1.23 ms nebo time<1 ms
|
||||
private static final Pattern LINUX_TIME_PATTERN = Pattern.compile("time[=<]\\s*([0-9.]+)");
|
||||
// Regex pro Windows: čas=1ms nebo time=1ms (anglická lokalizace) nebo doba=1ms
|
||||
private static final Pattern WINDOWS_TIME_PATTERN = Pattern.compile("(?:čas|time|doba)[=<]\\s*([0-9.]+)");
|
||||
|
||||
/**
|
||||
* Odešle jeden ICMP echo request.
|
||||
*
|
||||
* @param ip cílová IP adresa nebo hostname
|
||||
* @param timeoutSeconds timeout pro odpověď v sekundách
|
||||
* @return latenci v ms, nebo -1 pokud cil neodpověděl
|
||||
*/
|
||||
public static long ping(String ip, int timeoutSeconds) {
|
||||
try {
|
||||
ProcessBuilder pb;
|
||||
if (isWindows()) {
|
||||
// Windows: ping -n 1 -w timeoutMs ip
|
||||
int timeoutMs = timeoutSeconds * 1000;
|
||||
pb = new ProcessBuilder("ping", "-n", "1", "-w", String.valueOf(timeoutMs), ip);
|
||||
} else {
|
||||
// Linux/Unix: ping -c 1 -W timeoutSeconds ip
|
||||
pb = new ProcessBuilder("ping", "-c", "1", "-W", String.valueOf(timeoutSeconds), ip);
|
||||
}
|
||||
pb.redirectErrorStream(true);
|
||||
Process proc = pb.start();
|
||||
|
||||
String lastTimeMatch = null;
|
||||
try (BufferedReader reader = new BufferedReader(
|
||||
new InputStreamReader(proc.getInputStream()))) {
|
||||
String line;
|
||||
Pattern pattern = isWindows() ? WINDOWS_TIME_PATTERN : LINUX_TIME_PATTERN;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
Matcher m = pattern.matcher(line);
|
||||
if (m.find()) {
|
||||
lastTimeMatch = m.group(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean finished = proc.waitFor(timeoutSeconds + 2L, TimeUnit.SECONDS);
|
||||
if (!finished) {
|
||||
proc.destroyForcibly();
|
||||
return -1;
|
||||
}
|
||||
|
||||
int exitCode = proc.exitValue();
|
||||
// Na Windows je exit code 0 při úspěchu, na Linuxu také
|
||||
if (exitCode == 0 && lastTimeMatch != null) {
|
||||
return Math.round(Double.parseDouble(lastTimeMatch));
|
||||
}
|
||||
return -1;
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
return System.getProperty("os.name").toLowerCase().contains("win");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,276 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import com.sun.jna.Native;
|
||||
import com.sun.jna.NativeLong;
|
||||
import com.sun.jna.Pointer;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class RawIcmpPingEngine implements MonitorEngine {
|
||||
|
||||
private static final int AF_INET = 2;
|
||||
private static final int SOCK_RAW = 3;
|
||||
private static final int IPPROTO_ICMP = 1;
|
||||
private static final int SOL_SOCKET = 1;
|
||||
private static final int SO_RCVTIMEO = 20;
|
||||
private static final int SO_RCVBUF = 8;
|
||||
|
||||
private final ConcurrentHashMap<String, IpTarget> targets = new ConcurrentHashMap<>();
|
||||
private final CopyOnWriteArrayList<StatusListener> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
private final ExecutorService receiveExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
private final int cycleIntervalSeconds;
|
||||
private final int replyWaitMillis;
|
||||
private final int downThreshold;
|
||||
private final int identifier;
|
||||
|
||||
private final ConcurrentHashMap<Integer, IpTarget> sequenceToTarget = new ConcurrentHashMap<>();
|
||||
private final ConcurrentHashMap<Integer, Long> sequenceSentAtNanos = new ConcurrentHashMap<>();
|
||||
private final AtomicInteger sequenceCounter = new AtomicInteger(0);
|
||||
|
||||
private int socketFd = -1;
|
||||
private volatile boolean running = false;
|
||||
private ScheduledFuture<?> cycleHandle;
|
||||
|
||||
public RawIcmpPingEngine(int cycleIntervalSeconds, int replyWaitMillis) {
|
||||
this(cycleIntervalSeconds, replyWaitMillis, 2);
|
||||
}
|
||||
|
||||
public RawIcmpPingEngine(int cycleIntervalSeconds, int replyWaitMillis, int downThreshold) {
|
||||
this.cycleIntervalSeconds = cycleIntervalSeconds;
|
||||
this.replyWaitMillis = replyWaitMillis;
|
||||
this.downThreshold = Math.max(1, downThreshold);
|
||||
this.identifier = (int) (ProcessHandle.current().pid() & 0xFFFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addOrUpdateTarget(String nodeId, String ip) {
|
||||
targets.compute(nodeId, (k, existing) -> {
|
||||
if (existing == null) {
|
||||
return new IpTarget(nodeId, ip);
|
||||
} else {
|
||||
if (!existing.ip.equals(ip)) {
|
||||
existing.ip = ip;
|
||||
}
|
||||
return existing;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeTarget(String nodeId) {
|
||||
targets.remove(nodeId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTargets(Map<String, String> nodeIdToIp) {
|
||||
targets.keySet().retainAll(nodeIdToIp.keySet());
|
||||
for (Map.Entry<String, String> entry : nodeIdToIp.entrySet()) {
|
||||
addOrUpdateTarget(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<IpTarget> getTargets() {
|
||||
return targets.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addListener(StatusListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeListener(StatusListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
openSocket();
|
||||
running = true;
|
||||
receiveExecutor.submit(this::receiveLoop);
|
||||
cycleHandle = scheduler.scheduleAtFixedRate(this::runCycle, 0, cycleIntervalSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
running = false;
|
||||
if (cycleHandle != null) cycleHandle.cancel(true);
|
||||
scheduler.shutdownNow();
|
||||
receiveExecutor.shutdownNow();
|
||||
closeSocket();
|
||||
}
|
||||
|
||||
private void openSocket() {
|
||||
socketFd = CLibrary.INSTANCE.socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
|
||||
if (socketFd < 0) {
|
||||
throw new IllegalStateException(
|
||||
"Nepodařilo se otevřít RAW ICMP socket (errno=" + Native.getLastError() + "). "
|
||||
+ "Běžte program jako root, nebo nastavte capability: "
|
||||
+ "sudo setcap cap_net_raw+ep <cesta-k-java-binarce>");
|
||||
}
|
||||
|
||||
Timeval tv = new Timeval();
|
||||
tv.tv_sec = new NativeLong(0);
|
||||
tv.tv_usec = new NativeLong(200_000);
|
||||
CLibrary.INSTANCE.setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, tv, tv.size());
|
||||
|
||||
setReceiveBufferSize(1 << 20);
|
||||
}
|
||||
|
||||
private void setReceiveBufferSize(int bytes) {
|
||||
com.sun.jna.ptr.IntByReference size = new com.sun.jna.ptr.IntByReference(bytes);
|
||||
CLibrary.INSTANCE.setsockopt(socketFd, SOL_SOCKET, SO_RCVBUF, size, 4);
|
||||
}
|
||||
|
||||
private void closeSocket() {
|
||||
if (socketFd >= 0) {
|
||||
CLibrary.INSTANCE.close(socketFd);
|
||||
socketFd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
private void runCycle() {
|
||||
try {
|
||||
runCycleInternal();
|
||||
} catch (Throwable t) {
|
||||
System.err.println("runCycle selhal, cyklus VŠAK pokračuje dál:");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void runCycleInternal() {
|
||||
Set<Integer> sequencesThisCycle = new HashSet<>();
|
||||
|
||||
for (IpTarget target : targets.values()) {
|
||||
int seq = sequenceCounter.updateAndGet(v -> (v + 1) & 0xFFFF);
|
||||
sequencesThisCycle.add(seq);
|
||||
sequenceToTarget.put(seq, target);
|
||||
|
||||
SockAddrIn addr = new SockAddrIn();
|
||||
addr.sin_family = AF_INET;
|
||||
try {
|
||||
addr.sin_addr = InetAddress.getByName(target.ip).getAddress();
|
||||
} catch (Exception e) {
|
||||
sequenceToTarget.remove(seq);
|
||||
continue;
|
||||
}
|
||||
|
||||
byte[] payload = new byte[32];
|
||||
byte[] packet = IcmpPacketBuilder.buildEchoRequest(identifier, seq, payload);
|
||||
|
||||
sequenceSentAtNanos.put(seq, System.nanoTime());
|
||||
int sent = CLibrary.INSTANCE.sendto(socketFd, packet, packet.length, 0, addr, addr.size());
|
||||
if (sent < 0) {
|
||||
System.err.println("sendto selhal pro " + target.ip + " (errno=" + Native.getLastError() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
scheduler.schedule(() -> evaluateTimeouts(sequencesThisCycle), replyWaitMillis, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void receiveLoop() {
|
||||
byte[] buffer = new byte[1024];
|
||||
while (running) {
|
||||
try {
|
||||
int received = CLibrary.INSTANCE.recvfrom(socketFd, buffer, buffer.length, 0, Pointer.NULL, Pointer.NULL);
|
||||
if (received > 0) {
|
||||
IcmpPacketBuilder.ParsedReply reply = IcmpPacketBuilder.parseEchoReply(buffer, received);
|
||||
if (reply != null && reply.identifier() == identifier) {
|
||||
handleReply(reply.sequence());
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println("receiveLoop selhal, pokračuje dál:");
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleReply(int sequence) {
|
||||
IpTarget target = sequenceToTarget.remove(sequence);
|
||||
Long sentAtNanos = sequenceSentAtNanos.remove(sequence);
|
||||
if (target == null || sentAtNanos == null) return;
|
||||
|
||||
long latencyMs = Math.max(0, (System.nanoTime() - sentAtNanos) / 1_000_000);
|
||||
updateTarget(target, true, latencyMs);
|
||||
}
|
||||
|
||||
private void evaluateTimeouts(Set<Integer> sequencesFromThisCycle) {
|
||||
for (Integer seq : sequencesFromThisCycle) {
|
||||
IpTarget target = sequenceToTarget.remove(seq);
|
||||
sequenceSentAtNanos.remove(seq);
|
||||
if (target != null) {
|
||||
updateTarget(target, false, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ==================== UPRAVENÁ METODA ====================
|
||||
private void updateTarget(IpTarget target, boolean rawUp, long latencyMs) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
boolean previouslyReportedUp = target.up;
|
||||
boolean everCheckedBefore = target.everChecked;
|
||||
|
||||
|
||||
if (rawUp) {
|
||||
target.consecutiveOk++;
|
||||
target.consecutiveFails = 0;
|
||||
} else {
|
||||
target.consecutiveFails++;
|
||||
target.consecutiveOk = 0;
|
||||
}
|
||||
|
||||
boolean reportedUp;
|
||||
if (rawUp) {
|
||||
reportedUp = true;
|
||||
} else if (!everCheckedBefore) {
|
||||
reportedUp = false;
|
||||
} else {
|
||||
reportedUp = previouslyReportedUp && target.consecutiveFails < downThreshold;
|
||||
}
|
||||
|
||||
boolean stateChanged = everCheckedBefore && (reportedUp != previouslyReportedUp);
|
||||
boolean firstReport = !everCheckedBefore;
|
||||
|
||||
target.up = reportedUp;
|
||||
if (rawUp) {
|
||||
target.lastLatencyMs = latencyMs;
|
||||
} else if (!reportedUp) {
|
||||
target.lastLatencyMs = -1;
|
||||
}
|
||||
target.lastCheck = now;
|
||||
target.everChecked = true;
|
||||
if (stateChanged) target.lastChange = now;
|
||||
|
||||
StatusEvent event = new StatusEvent(
|
||||
target.nodeId,
|
||||
target.ip,
|
||||
reportedUp,
|
||||
target.lastLatencyMs,
|
||||
stateChanged,
|
||||
firstReport,
|
||||
now
|
||||
);
|
||||
|
||||
for (StatusListener listener : listeners) {
|
||||
listener.onUpdate(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Odpovida C strukture "struct sockaddr_in" (viz <netinet/in.h>).
|
||||
* sin_addr drzime primo jako 4 bajty (presne v poradi, v jakem je vraci
|
||||
* InetAddress.getAddress() - tedy uz ve "network byte order"), abychom se
|
||||
* vyhnuli zamene endianity pri prevodu na/z int.
|
||||
*
|
||||
* DULEZITE: trida MUSI byt public, jinak na ni JNA nemuze sahat reflexi
|
||||
* z jineho balicku (IllegalAccessException i pres public pole uvnitr).
|
||||
*/
|
||||
public class SockAddrIn extends Structure {
|
||||
public short sin_family;
|
||||
public short sin_port;
|
||||
public byte[] sin_addr = new byte[4];
|
||||
public byte[] sin_zero = new byte[8];
|
||||
|
||||
@Override
|
||||
protected List<String> getFieldOrder() {
|
||||
return Arrays.asList("sin_family", "sin_port", "sin_addr", "sin_zero");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
public interface StatusChangeListener {
|
||||
void onStatusChanged(String ip, String newStatus);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Jedna udalost o vysledku kontroly konkretni IP adresy.
|
||||
* Predava se registrovanym listenerum (napr. pro broadcast pres Netty).
|
||||
*
|
||||
* @param ip IP adresa / hostname
|
||||
* @param id id cile
|
||||
* @param up true = cil odpovedel, false = neodpovedel (timeout)
|
||||
* @param latencyMs latence v ms, pokud up == true; pokud up == false, je vzdy -1
|
||||
* @param stateChanged true, pokud se stav zmenil oproti predchozi kontrole (UP<->DOWN)
|
||||
* @param timestamp cas kontroly
|
||||
*/
|
||||
public record StatusEvent(
|
||||
String nodeId,
|
||||
String ip,
|
||||
boolean up,
|
||||
long latencyMs,
|
||||
boolean stateChanged,
|
||||
boolean firstReport, // true pro první hlášení po kontrole
|
||||
LocalDateTime timestamp
|
||||
) {
|
||||
public String describe() {
|
||||
if (up) {
|
||||
return "Node " + nodeId + " (" + ip + ") -> UP, odezva " + latencyMs + " ms";
|
||||
} else {
|
||||
return "Node " + nodeId + " (" + ip + ") -> DOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
/**
|
||||
* Implementujte toto rozhrani, abyste dostavali vysledky kontrol.
|
||||
* Volano asynchronne z interniho ping-poolu po KAZDE kontrole (nejen pri
|
||||
* zmene stavu) - v StatusEvent.stateChanged() poznate, jestli doslo ke zmene.
|
||||
*
|
||||
* Typicke pouziti: v implementaci rozeslat zpravu vsem pripojenym Netty
|
||||
* klientum (napr. pres ChannelGroup.writeAndFlush(...)).
|
||||
*
|
||||
* Implementace by mela byt rychla a neblokujici - vola se primo z vlakna
|
||||
* ping-poolu.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface StatusListener {
|
||||
void onUpdate(StatusEvent event);
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package jnet.server.probe.ping;
|
||||
|
||||
import com.sun.jna.NativeLong;
|
||||
import com.sun.jna.Structure;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Odpovida C strukture "struct timeval" (viz <sys/time.h>), pouzivane pro
|
||||
* nastaveni SO_RCVTIMEO (timeout na recvfrom).
|
||||
*
|
||||
* DULEZITE: trida MUSI byt public, jinak na ni JNA nemuze sahat reflexi
|
||||
* z jineho balicku (IllegalAccessException i pres public pole uvnitr).
|
||||
*/
|
||||
public class Timeval extends Structure {
|
||||
public NativeLong tv_sec;
|
||||
public NativeLong tv_usec;
|
||||
|
||||
@Override
|
||||
protected List<String> getFieldOrder() {
|
||||
return Arrays.asList("tv_sec", "tv_usec");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package jnet.server.probe.snmp;
|
||||
|
||||
|
||||
public class MonitorConfig {
|
||||
public int id; // unikátní ID, které si uživatel zvolí
|
||||
public String ip;
|
||||
public String community;
|
||||
public String port = "161";
|
||||
public int version;
|
||||
public String oid;
|
||||
public int interval; // v sekundách
|
||||
|
||||
public MonitorConfig() {}
|
||||
|
||||
public MonitorConfig(int id, String ip, String community, String port, int version, String oid, int interval) {
|
||||
this.id = id;
|
||||
this.ip = ip;
|
||||
this.community = community;
|
||||
this.port = port;
|
||||
this.version = version;
|
||||
this.oid = oid;
|
||||
this.interval = interval;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
package jnet.server.probe.snmp;
|
||||
|
||||
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.TransportMapping;
|
||||
import org.snmp4j.mp.SnmpConstants;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.OctetString;
|
||||
import org.snmp4j.smi.UdpAddress;
|
||||
import org.snmp4j.transport.DefaultUdpTransportMapping;
|
||||
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeProbe;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.lib.object.SnmpProfile;
|
||||
import jnet.server.Server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jnet.lib.LogFile;
|
||||
|
||||
public class NodeProbeManager implements AutoCloseable {
|
||||
private Snmp snmp = null;
|
||||
private ScheduledExecutorService scheduler = null;
|
||||
private final ConcurrentHashMap<Integer, TaskEntry> tasks = new ConcurrentHashMap<>();
|
||||
private final List<SnmpResultListener> listeners = new CopyOnWriteArrayList<>();
|
||||
|
||||
private static class TaskEntry {
|
||||
final MonitorConfig config;
|
||||
final ScheduledFuture<?> future;
|
||||
final SnmpMonitorTask task;
|
||||
TaskEntry(MonitorConfig config, ScheduledFuture<?> future, SnmpMonitorTask task) {
|
||||
this.config = config;
|
||||
this.future = future;
|
||||
this.task = task;
|
||||
}
|
||||
}
|
||||
|
||||
public NodeProbeManager() {
|
||||
try {
|
||||
TransportMapping<?> transport = new DefaultUdpTransportMapping();
|
||||
transport.listen();
|
||||
this.snmp = new Snmp(transport);
|
||||
this.scheduler = Executors.newScheduledThreadPool(10);
|
||||
} catch (Exception ex) {
|
||||
LogFile.printDebug("[NodeProbeManager] Error: " + ex.getMessage());
|
||||
}
|
||||
|
||||
loadTask();
|
||||
}
|
||||
|
||||
public void loadTask() {
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
SnmpProfile profile = Server.snmpProfile.stream()
|
||||
.filter(p -> p.getId() == node.getSnmpProfile())
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
for (NodeProbe nodeProbe : node.getProbe()) {
|
||||
MonitorConfig mc = new MonitorConfig(
|
||||
nodeProbe.getId(),
|
||||
node.getIp(),
|
||||
profile.getCommunityRead(),
|
||||
profile.getPort(),
|
||||
profile.getVersion(),
|
||||
nodeProbe.getOid(),
|
||||
nodeProbe.getInterval()
|
||||
);
|
||||
addTask(mc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Přidá úlohu s ID z config.id. Pokud už ID existuje, vyhodí výjimku.
|
||||
*/
|
||||
public synchronized void addTask(MonitorConfig cfg) {
|
||||
if (tasks.containsKey(cfg.id)) {
|
||||
throw new IllegalArgumentException("Task s ID " + cfg.id + " již existuje.");
|
||||
}
|
||||
CommunityTarget target = createTarget(cfg);
|
||||
OID oid = new OID(cfg.oid);
|
||||
String identifier = cfg.ip + ":" + cfg.oid;
|
||||
|
||||
SnmpMonitorTask task = new SnmpMonitorTask(cfg.id, snmp, target, oid, identifier, listeners);
|
||||
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(task, 0, cfg.interval, TimeUnit.SECONDS);
|
||||
tasks.put(cfg.id, new TaskEntry(cfg, future, task));
|
||||
LogFile.printDebug("[NodeProbe Manager] Přidána úloha ID " + cfg.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Odebere úlohu podle ID.
|
||||
*/
|
||||
public synchronized boolean removeTask(int id) {
|
||||
TaskEntry entry = tasks.remove(id);
|
||||
if (entry != null) {
|
||||
entry.future.cancel(false);
|
||||
LogFile.printDebug("[NodeProbe Manager] Odebrána úloha ID " + id);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vrátí kopii seznamu aktivních úloh.
|
||||
*/
|
||||
public synchronized List<MonitorConfig> getTasks() {
|
||||
List<MonitorConfig> list = new ArrayList<>();
|
||||
for (TaskEntry e : tasks.values()) {
|
||||
list.add(e.config);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
// --- Listener registrace ---
|
||||
public void addListener(SnmpResultListener listener) {
|
||||
listeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeListener(SnmpResultListener listener) {
|
||||
listeners.remove(listener);
|
||||
}
|
||||
|
||||
// --- pomocné ---
|
||||
private CommunityTarget createTarget(MonitorConfig cfg) {
|
||||
CommunityTarget target = new CommunityTarget();
|
||||
target.setAddress(new UdpAddress(cfg.ip + "/" + cfg.port));
|
||||
target.setCommunity(new OctetString(cfg.community));
|
||||
target.setVersion(SnmpConstants.version2c);
|
||||
target.setTimeout(3000);
|
||||
target.setRetries(1);
|
||||
return target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
LogFile.printInfo("[NodeProbe Manager] Ukončuji...");
|
||||
try { snmp.close(); } catch (IOException e) { LogFile.printErr("[NodeProbe Manager] Error: " + e.getMessage()); }
|
||||
scheduler.shutdownNow();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package jnet.server.probe.snmp;
|
||||
|
||||
import jnet.lib.object.Node;
|
||||
import jnet.lib.object.NodeProbe;
|
||||
import jnet.lib.object.Site;
|
||||
import jnet.server.Server;
|
||||
import jnet.server.networkserver.ServerHandler;
|
||||
import jnet.lib.Message;
|
||||
import org.snmp4j.smi.Variable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import jnet.lib.object.SnmpResult;
|
||||
|
||||
/**
|
||||
* Zpracovává výsledky SNMP dotazů: - ihned aktualizuje lokální cache
|
||||
* (NodeProbe.value) - ukládá výsledky/chyby do fronty - každých N sekund odešle
|
||||
* dávku všem klientům
|
||||
*/
|
||||
public class SnmpBatchProcessor implements SnmpResultListener, AutoCloseable {
|
||||
|
||||
private final BlockingQueue<SnmpResult> queue = new LinkedBlockingQueue<>();
|
||||
private final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
|
||||
private final int batchIntervalSeconds;
|
||||
private NodeProbeManager manager;
|
||||
|
||||
public SnmpBatchProcessor(int batchIntervalSeconds) {
|
||||
this.batchIntervalSeconds = batchIntervalSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inicializuje procesor: zaregistruje se jako listener a spustí periodické
|
||||
* odesílání.
|
||||
*
|
||||
* @param manager SnmpProbeManager, ke kterému se připojí
|
||||
*/
|
||||
public void init(NodeProbeManager manager) {
|
||||
this.manager = manager;
|
||||
manager.addListener(this);
|
||||
start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Spustí periodické odesílání dávek.
|
||||
*/
|
||||
private void start() {
|
||||
scheduler.scheduleAtFixedRate(this::flushBatch, batchIntervalSeconds, batchIntervalSeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zastaví periodickou úlohu, odešle zbylé položky a odregistruje se z
|
||||
* manageru.
|
||||
*/
|
||||
@Override
|
||||
public void close() {
|
||||
scheduler.shutdownNow();
|
||||
// odešle zbylé položky
|
||||
flushBatch();
|
||||
if (manager != null) {
|
||||
manager.removeListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
// --- Implementace SnmpResultListener ---
|
||||
@Override
|
||||
public void onResult(int taskId, String oid, Variable value) {
|
||||
queue.offer(new SnmpResult(taskId, oid, value, null, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(int taskId, String oid, String error) {
|
||||
// Chyby také zařadíme do fronty (pro informování klientů)
|
||||
queue.offer(new SnmpResult(taskId, oid, null, error, false));
|
||||
}
|
||||
|
||||
// --- interní metody ---
|
||||
/**
|
||||
* Vybere všechny položky z fronty a odešle je jako jednu dávku.
|
||||
*/
|
||||
private void flushBatch() {
|
||||
List<SnmpResult> batch = new ArrayList<>();
|
||||
queue.drainTo(batch);
|
||||
if (!batch.isEmpty()) {
|
||||
|
||||
// 1. Ihned aktualizovat lokální cache (NodeProbe)
|
||||
for (SnmpResult snmpResult : batch) {
|
||||
updateNodeProbeValue(snmpResult.getTaskId(), snmpResult.getValue());
|
||||
}
|
||||
// 2. Odeslat
|
||||
ServerHandler.sendAll(Message.SNMP_PROBE_VALUE, batch);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Najde NodeProbe podle taskId a nastaví mu hodnotu. (Převzato z původního
|
||||
* listeneru v Server.java)
|
||||
*/
|
||||
private void updateNodeProbeValue(int idProbe, Object value) {
|
||||
for (Site site : Server.site) {
|
||||
for (Node node : site.getNode()) {
|
||||
for (NodeProbe nodeProbe : node.getProbe()) {
|
||||
if (nodeProbe.getId() == idProbe) {
|
||||
nodeProbe.setValue((Variable) value);
|
||||
return; // nalezeno
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package jnet.server.probe.snmp;
|
||||
|
||||
import org.snmp4j.CommunityTarget;
|
||||
import org.snmp4j.PDU;
|
||||
import org.snmp4j.Snmp;
|
||||
import org.snmp4j.event.ResponseEvent;
|
||||
import org.snmp4j.smi.OID;
|
||||
import org.snmp4j.smi.VariableBinding;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import org.snmp4j.smi.Variable;
|
||||
|
||||
public class SnmpMonitorTask implements Runnable {
|
||||
private final int taskId;
|
||||
private final Snmp snmp;
|
||||
private final CommunityTarget target;
|
||||
private final OID oid;
|
||||
private final String identifier;
|
||||
private final List<SnmpResultListener> listeners;
|
||||
|
||||
public SnmpMonitorTask(int taskId, Snmp snmp, CommunityTarget target, OID oid,
|
||||
String identifier, List<SnmpResultListener> listeners) {
|
||||
this.taskId = taskId;
|
||||
this.snmp = snmp;
|
||||
this.target = target;
|
||||
this.oid = oid;
|
||||
this.identifier = identifier;
|
||||
this.listeners = listeners;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
PDU pdu = new PDU();
|
||||
pdu.add(new VariableBinding(oid));
|
||||
pdu.setType(PDU.GET);
|
||||
|
||||
ResponseEvent event = snmp.send(pdu, target);
|
||||
|
||||
if (event == null) {
|
||||
notifyError("Žádná odpověď (timeout)");
|
||||
return;
|
||||
}
|
||||
PDU response = event.getResponse();
|
||||
if (response == null) {
|
||||
notifyError("Timeout / agent nedostupný");
|
||||
return;
|
||||
}
|
||||
int errorStatus = response.getErrorStatus();
|
||||
if (errorStatus != PDU.noError) {
|
||||
notifyError("SNMP chyba: " + response.getErrorStatusText());
|
||||
return;
|
||||
}
|
||||
VariableBinding vb = response.get(0);
|
||||
if (vb != null) {
|
||||
Variable value = vb.getVariable();
|
||||
notifyResult(value);
|
||||
// také log
|
||||
// System.out.println("[" + getCurrentTime() + "] [Task " + taskId + "] " + identifier + " = " + value);
|
||||
} else {
|
||||
notifyError("Prázdná odpověď");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
notifyError("Výjimka: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyResult(Variable value) {
|
||||
for (SnmpResultListener l : listeners) {
|
||||
try { l.onResult(taskId, oid.toString(), value); } catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyError(String error) {
|
||||
for (SnmpResultListener l : listeners) {
|
||||
try { l.onError(taskId, oid.toString(), error); } catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
|
||||
private String getCurrentTime() {
|
||||
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue