This commit is contained in:
Dmitry Isaenko 2020-10-20 18:19:20 +03:00
parent 3cf0e2fa0f
commit 89fce149df
24 changed files with 354 additions and 310 deletions

View file

@ -5,7 +5,7 @@ Another one IRC bot in deep-deep beta.
## License ## License
Source code spreads under the GNU General Public License v3 or higher. Please see LICENSE file. Source code spreads under the GNU General Public License v3 or higher. Please see LICENSE file.
####Used libraries: #### Used libraries:
* Apache commons CLI: https://commons.apache.org/proper/commons-cli/ * Apache commons CLI: https://commons.apache.org/proper/commons-cli/
* GSON: https://github.com/google/gson * GSON: https://github.com/google/gson
* sqliteJDBC: https://bitbucket.org/xerial/sqlite-jdbc * sqliteJDBC: https://bitbucket.org/xerial/sqlite-jdbc

View file

@ -77,11 +77,6 @@
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
<excludes>
<exclude>
**/Temporary/*
</exclude>
</excludes>
</configuration> </configuration>
</plugin> </plugin>
<plugin> <plugin>

View file

@ -1,5 +1,10 @@
package InnaIrcBot; package InnaIrcBot;
import InnaIrcBot.logging.LogDriver;
import java.util.ArrayList;
import java.util.List;
public class GlobalData { public class GlobalData {
private static final String version = "InnaIrcBot v0.8 \"Коммунарка\""; private static final String version = "InnaIrcBot v0.8 \"Коммунарка\"";
public static synchronized String getAppVersion(){ public static synchronized String getAppVersion(){

View file

@ -1,74 +0,0 @@
package InnaIrcBot.LogDriver;
import java.util.HashMap;
public class BotDriver {
private final static HashMap<String, String[][]> serverDriver = new HashMap<>();
private final static HashMap<String, BotSystemWorker> systemLogWorkerMap = new HashMap<>();
/**
* Define driver for desired server
* */
// TODO: add proxy worker for using with multiple drivers
public static synchronized boolean setLogDriver(String serverName, String driver, String[] driverParams, String applicationLogDir){
if (driver == null)
return false;
if (driver.isEmpty())
return false;
if (driverParams.length == 0)
return false;
if (driverParams[0] == null)
return false;
if (driverParams[0].isEmpty())
return false;
String[][] drvAndParams = {
{driver},
driverParams
};
serverDriver.put(serverName, drvAndParams);
systemLogWorkerMap.put(serverName, new BotSystemWorker(serverName, applicationLogDir));
return true;
}
public static synchronized Worker getWorker(String server, String channel){
if (serverDriver.containsKey(server)) {
switch (serverDriver.get(server)[0][0].toLowerCase()) {
case "files":
BotFilesWorker botFilesWorker = new BotFilesWorker(server, serverDriver.get(server)[1], channel);
return validateConsistancy(botFilesWorker, server, channel);
case "sqlite":
BotSQLiteWorker botSQLiteWorker = new BotSQLiteWorker(server, serverDriver.get(server)[1], channel);
return validateConsistancy(botSQLiteWorker, server, channel);
case "mongodb":
BotMongoWorker botMongoWorker = new BotMongoWorker(server, serverDriver.get(server)[1], channel);
return validateConsistancy(botMongoWorker, server, channel);
case "zero":
return new BotZeroWorker();
default:
System.out.println("BotDriver->getWorker(): Configuration issue: can't find required driver \""
+serverDriver.get(server)[0][0]
+"\".Using \"ZeroWorker\".");
return new BotZeroWorker();
}
}
System.out.println("Issue on BotDriver->getWorker(): Channel requested for non-existing server?\n" +
"\tUsing ZeroWorker.");
return new BotZeroWorker();
}
// If channel found that it's impossible to use defined worker from user settings and asking for use ZeroWorker
public static synchronized Worker getZeroWorker(){ return new BotZeroWorker(); }
public static synchronized BotSystemWorker getSystemWorker(String serverName){
return systemLogWorkerMap.get(serverName);
}
private static Worker validateConsistancy(Worker worker, String server, String channel){ // synchronized?
if (worker.isConsistent()){
return worker;
}
System.out.println("BotDriver->validateConstancy(): Unable to use "
+worker.getClass().getSimpleName()+" for "+server+"/"+channel
+". Using ZeroWorker instead.");
return new BotZeroWorker();
}
}

View file

@ -1,12 +0,0 @@
package InnaIrcBot.LogDriver;
public interface SystemWorker {
void registerInSystemWorker(ThingToCloseOnDie thing);
void logAdd(String event,
String initiatorArg,
String messageArg);
void close();
}

View file

@ -1,5 +0,0 @@
package InnaIrcBot.LogDriver;
public interface ThingToCloseOnDie {
void die();
}

View file

@ -3,8 +3,8 @@ package InnaIrcBot.ProvidersConsumers;
import InnaIrcBot.Commanders.ChanelCommander; import InnaIrcBot.Commanders.ChanelCommander;
import InnaIrcBot.GlobalData; import InnaIrcBot.GlobalData;
import InnaIrcBot.IrcChannel; import InnaIrcBot.IrcChannel;
import InnaIrcBot.LogDriver.BotDriver; import InnaIrcBot.logging.LogDriver;
import InnaIrcBot.LogDriver.Worker; import InnaIrcBot.logging.Worker;
import InnaIrcBot.config.ConfigurationManager; import InnaIrcBot.config.ConfigurationManager;
import java.time.LocalTime; import java.time.LocalTime;
@ -38,7 +38,7 @@ public class ChanConsumer implements Runnable {
this.chanConsumerQueue = thisIrcChannel.getChannelQueue(); this.chanConsumerQueue = thisIrcChannel.getChannelQueue();
this.serverName = serverName; this.serverName = serverName;
this.channelName = thisIrcChannel.toString(); this.channelName = thisIrcChannel.toString();
this.writerWorker = BotDriver.getWorker(serverName, channelName); this.writerWorker = LogDriver.getWorker(serverName, channelName);
this.userList = new ArrayList<>(); this.userList = new ArrayList<>();
this.nick = ownNick; this.nick = ownNick;
this.rejoin = ConfigurationManager.getConfiguration(serverName).getRejoinOnKick(); this.rejoin = ConfigurationManager.getConfiguration(serverName).getRejoinOnKick();
@ -145,9 +145,9 @@ public class ChanConsumer implements Runnable {
private void fixLogDriverIssues(String a, String b, String c){ private void fixLogDriverIssues(String a, String b, String c){
System.out.println("ChanConsumer (@"+serverName+"/"+channelName+")->fixLogDriverIssues(): Some issues detected. Trying to fix..."); System.out.println("ChanConsumer (@"+serverName+"/"+channelName+")->fixLogDriverIssues(): Some issues detected. Trying to fix...");
this.writerWorker = BotDriver.getWorker(serverName, channelName); // Reset logDriver and try using the same one this.writerWorker = LogDriver.getWorker(serverName, channelName); // Reset logDriver and try using the same one
if (! writerWorker.logAdd(a, b, c)){ // Write to it what was not written (most likely) and if it's still not consistent: if (! writerWorker.logAdd(a, b, c)){ // Write to it what was not written (most likely) and if it's still not consistent:
this.writerWorker = BotDriver.getZeroWorker(); this.writerWorker = LogDriver.getZeroWorker();
System.out.println("ChanConsumer (@"+serverName+"/"+channelName+")->fixLogDriverIssues(): failed to use defined LogDriver. Using ZeroWorker instead."); System.out.println("ChanConsumer (@"+serverName+"/"+channelName+")->fixLogDriverIssues(): failed to use defined LogDriver. Using ZeroWorker instead.");
} }
} }

View file

@ -2,7 +2,7 @@ package InnaIrcBot.ProvidersConsumers;
import InnaIrcBot.config.ConfigurationFile; import InnaIrcBot.config.ConfigurationFile;
import InnaIrcBot.IrcChannel; import InnaIrcBot.IrcChannel;
import InnaIrcBot.LogDriver.BotDriver; import InnaIrcBot.logging.LogDriver;
import InnaIrcBot.ReconnectControl; import InnaIrcBot.ReconnectControl;
import java.io.*; import java.io.*;
@ -16,16 +16,16 @@ import java.util.concurrent.BlockingQueue;
public class DataProvider implements Runnable { public class DataProvider implements Runnable {
private final ConfigurationFile configurationFile; private final ConfigurationFile configurationFile;
private final String serverName; private final String server;
private final String nickName; private final String nickName;
private BufferedReader rawStreamReader; private BufferedReader mainReader;
/** /**
* Initiate connection and prepare input/output streams for run() * Initiate connection and prepare input/output streams for run()
* */ * */
public DataProvider(ConfigurationFile configurationFile){ public DataProvider(ConfigurationFile configurationFile){
this.configurationFile = configurationFile; this.configurationFile = configurationFile;
this.serverName = configurationFile.getServerName(); this.server = configurationFile.getServerName();
this.nickName = configurationFile.getUserNick(); this.nickName = configurationFile.getUserNick();
} }
@ -35,18 +35,17 @@ public class DataProvider implements Runnable {
} catch (Exception e){ } catch (Exception e){
System.out.println("Internal issue: DataProvider->run() caused exception:\n\t"+e.getMessage()); System.out.println("Internal issue: DataProvider->run() caused exception:\n\t"+e.getMessage());
e.printStackTrace(); e.printStackTrace();
}
ReconnectControl.register(serverName); close();
if (! BotDriver.setLogDriver(serverName,
configurationFile.getLogDriver(),
configurationFile.getLogDriverParameters(),
configurationFile.getApplicationLogDir())) { //Prepare logDriver for using in threads.)
this.close();
return; return;
} }
ReconnectControl.register(server);
LogDriver.setLogDriver(server,
configurationFile.getLogDriverConfiguration(),
configurationFile.getApplicationLogDir());
/* Used for sending data into consumers objects*/ /* Used for sending data into consumers objects*/
Map<String, IrcChannel> ircChannels = Collections.synchronizedMap(new HashMap<>()); Map<String, IrcChannel> ircChannels = Collections.synchronizedMap(new HashMap<>());
@ -57,19 +56,19 @@ public class DataProvider implements Runnable {
new SystemConsumer(systemConsumerQueue, nickName, ircChannels, this.configurationFile)); new SystemConsumer(systemConsumerQueue, nickName, ircChannels, this.configurationFile));
SystemConsumerThread.start(); SystemConsumerThread.start();
StreamProvider.setSysConsumer(serverName, systemConsumerQueue); // Register system consumer at StreamProvider StreamProvider.setSysConsumer(server, systemConsumerQueue); // Register system consumer at StreamProvider
ircChannels.put(systemConsumerChannel.toString(), systemConsumerChannel); // Not sure that PrintWriter is thread-safe.. ircChannels.put(systemConsumerChannel.toString(), systemConsumerChannel); // Not sure that PrintWriter is thread-safe..
////////////////////////////////////// Start loop ////////////////////////////////////////////////////////////// ////////////////////////////////////// Start loop //////////////////////////////////////////////////////////////
StreamProvider.writeToStream(serverName,"NICK "+this.nickName); StreamProvider.writeToStream(server,"NICK "+this.nickName);
StreamProvider.writeToStream(serverName,"USER "+ configurationFile.getUserIdent()+" 8 * :"+ configurationFile.getUserRealName()); // TODO: Add usermode 4 rusnet StreamProvider.writeToStream(server,"USER "+ configurationFile.getUserIdent()+" 8 * :"+ configurationFile.getUserRealName()); // TODO: Add usermode 4 rusnet
try { try {
String rawMessage; String rawMessage;
String[] rawStrings; // prefix[0] command[1] command-parameters\r\n[2] String[] rawStrings; // prefix[0] command[1] command-parameters\r\n[2]
//if there is no prefix, you should assume the message came from your client. //if there is no prefix, you should assume the message came from your client.
while ((rawMessage = rawStreamReader.readLine()) != null) { while ((rawMessage = mainReader.readLine()) != null) {
System.out.println(rawMessage); System.out.println(rawMessage);
if (rawMessage.startsWith(":")) { if (rawMessage.startsWith(":")) {
rawStrings = rawMessage rawStrings = rawMessage
@ -101,7 +100,7 @@ public class DataProvider implements Runnable {
} }
} }
} catch (IOException e){ } catch (IOException e){
System.out.println("Socket issue: I/O exception"); //Connection closed. TODO: MAYBE try reconnect System.out.println("Socket issue: I/O exception: "+e.getMessage()); //Connection closed. TODO: MAYBE try reconnect
} }
finally { finally {
SystemConsumerThread.interrupt(); SystemConsumerThread.interrupt();
@ -111,7 +110,7 @@ public class DataProvider implements Runnable {
private void connect() throws Exception{ private void connect() throws Exception{
final int port = configurationFile.getServerPort(); final int port = configurationFile.getServerPort();
InetAddress inetAddress = InetAddress.getByName(serverName); InetAddress inetAddress = InetAddress.getByName(server);
Socket socket = new Socket(); // TODO: set timeout? Socket socket = new Socket(); // TODO: set timeout?
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
socket.connect(new InetSocketAddress(inetAddress, port), 5000); // 5sec socket.connect(new InetSocketAddress(inetAddress, port), 5000); // 5sec
@ -121,20 +120,19 @@ public class DataProvider implements Runnable {
if (! socket.isConnected()) if (! socket.isConnected())
throw new Exception("Unable to connect server."); throw new Exception("Unable to connect server.");
StreamProvider.setStream(serverName, socket); StreamProvider.setStream(server, socket);
InputStream inStream = socket.getInputStream(); InputStream inStream = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(inStream, StandardCharsets.UTF_8); //TODO set charset in options; InputStreamReader isr = new InputStreamReader(inStream, StandardCharsets.UTF_8); //TODO set charset in options;
rawStreamReader = new BufferedReader(isr); mainReader = new BufferedReader(isr);
} }
private void sendPingReply(String rawData){ private void sendPingReply(String rawData){
StreamProvider.writeToStream(serverName,"PONG :" + rawData.replace("PING :", "")); StreamProvider.writeToStream(server,"PONG :" + rawData.replace("PING :", ""));
} }
//HANDLE ALWAYS in case thread decided to die
private void close(){ private void close(){
StreamProvider.delStream(serverName); StreamProvider.delStream(server);
ReconnectControl.notify(serverName); ReconnectControl.notify(server);
} }
} }

View file

@ -6,8 +6,8 @@ import InnaIrcBot.ReconnectControl;
import InnaIrcBot.config.ConfigurationFile; import InnaIrcBot.config.ConfigurationFile;
import InnaIrcBot.GlobalData; import InnaIrcBot.GlobalData;
import InnaIrcBot.IrcChannel; import InnaIrcBot.IrcChannel;
import InnaIrcBot.LogDriver.BotDriver; import InnaIrcBot.logging.LogDriver;
import InnaIrcBot.LogDriver.BotSystemWorker; import InnaIrcBot.logging.WorkerSystem;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
@ -19,7 +19,7 @@ import java.util.concurrent.BlockingQueue;
public class SystemConsumer implements Runnable{ public class SystemConsumer implements Runnable{
private final BlockingQueue<String> systemQueue; private final BlockingQueue<String> systemQueue;
private BotSystemWorker writerWorker; private WorkerSystem writerWorker;
private String nick; private String nick;
private String serverName; private String serverName;
private final Map<String, IrcChannel> channels; private final Map<String, IrcChannel> channels;
@ -34,7 +34,7 @@ public class SystemConsumer implements Runnable{
SystemConsumer(BlockingQueue<String> systemQueue, String userNick, Map<String, IrcChannel> channels, ConfigurationFile configurationFile) { SystemConsumer(BlockingQueue<String> systemQueue, String userNick, Map<String, IrcChannel> channels, ConfigurationFile configurationFile) {
this.systemQueue = systemQueue; this.systemQueue = systemQueue;
this.writerWorker = BotDriver.getSystemWorker(configurationFile.getServerName()); this.writerWorker = LogDriver.getSystemWorker(configurationFile.getServerName());
this.nick = userNick; this.nick = userNick;
this.serverName = configurationFile.getServerName(); this.serverName = configurationFile.getServerName();
this.channels = channels; this.channels = channels;

View file

@ -18,6 +18,8 @@ public class ConfigurationFile {
private String chanelConfigurationsPath; private String chanelConfigurationsPath;
private String applicationLogDir; private String applicationLogDir;
private LogDriverConfiguration logDriverConfiguration;
public ConfigurationFile(String serverName, public ConfigurationFile(String serverName,
int serverPort, int serverPort,
String serverPass, String serverPass,
@ -63,8 +65,11 @@ public class ConfigurationFile {
public String getUserNickAuthStyle() { return nonNullString(userNickAuthStyle); } public String getUserNickAuthStyle() { return nonNullString(userNickAuthStyle); }
public String getUserMode() { return nonNullString(userMode); } public String getUserMode() { return nonNullString(userMode); }
public boolean getRejoinOnKick() { return rejoinOnKick; } public boolean getRejoinOnKick() { return rejoinOnKick; }
public String getLogDriver() { return nonNullString(logDriver); }
public String[] getLogDriverParameters() { return logDriverParameters; } public LogDriverConfiguration getLogDriverConfiguration(){
return new LogDriverConfiguration(nonNullString(logDriver).toLowerCase(), logDriverParameters);
}
public String getBotAdministratorPassword() { return nonNullString(botAdministratorPassword); } public String getBotAdministratorPassword() { return nonNullString(botAdministratorPassword); }
public String getChanelConfigurationsPath() { return nonNullString(chanelConfigurationsPath); } public String getChanelConfigurationsPath() { return nonNullString(chanelConfigurationsPath); }
public String getApplicationLogDir() { return nonNullString(applicationLogDir); } public String getApplicationLogDir() { return nonNullString(applicationLogDir); }

View file

@ -0,0 +1,40 @@
package InnaIrcBot.config;
import InnaIrcBot.logging.SupportedLogDrivers;
public class LogDriverConfiguration {
private String name;
private String[] params;
public LogDriverConfiguration(String name, String[] params){
this.name = name.toLowerCase();
this.params = params;
validateName();
validateParams();
}
private void validateName(){
if (! SupportedLogDrivers.contains(name)) {
name = SupportedLogDrivers.zero;
}
}
private void validateParams(){
if (params == null) {
name = SupportedLogDrivers.zero;
return;
}
if (params.length == 0){
name = SupportedLogDrivers.zero;
return;
}
if (params[0] == null){
name = SupportedLogDrivers.zero;
return;
}
if (params[0].isEmpty()){
name = SupportedLogDrivers.zero;
}
}
public String getName() { return name; }
public String[] getParams() { return params; }
}

View file

@ -0,0 +1,62 @@
package InnaIrcBot.logging;
import InnaIrcBot.ProvidersConsumers.StreamProvider;
import InnaIrcBot.config.LogDriverConfiguration;
import java.util.HashMap;
public class LogDriver {
private final static HashMap<String, String[][]> serverDriver = new HashMap<>();
private final static HashMap<String, WorkerSystem> systemLogWorkerMap = new HashMap<>();
/**
* Define driver for desired server
* */
// TODO: add proxy worker for using with multiple drivers
public static synchronized void setLogDriver(String server,
LogDriverConfiguration logDriverConfiguration,
String applicationLogDir){
String[][] drvAndParams = {
{logDriverConfiguration.getName()},
logDriverConfiguration.getParams()
};
serverDriver.put(server, drvAndParams);
systemLogWorkerMap.put(server, new WorkerSystem(server, applicationLogDir));
}
public static synchronized Worker getWorker(String server, String channel){
if (serverDriver.containsKey(server)) {
switch (serverDriver.get(server)[0][0]) {
case "files":
WorkerFiles workerFiles = new WorkerFiles(server, serverDriver.get(server)[1], channel);
return validateConsistancy(workerFiles, server, channel);
case "sqlite":
WorkerSQLite workerSQLite = new WorkerSQLite(server, serverDriver.get(server)[1], channel);
return validateConsistancy(workerSQLite, server, channel);
case "mongodb":
WorkerMongoDB workerMongoDB = new WorkerMongoDB(server, serverDriver.get(server)[1], channel);
return validateConsistancy(workerMongoDB, server, channel);
case "zero":
return new WorkerZero();
}
}
System.out.println("Issue on BotDriver->getWorker(): Channel requested for non-existing server?\n" +
"\tUsing ZeroWorker.");
return new WorkerZero();
}
// If channel found that it's impossible to use defined worker from user settings and asking for use ZeroWorker
public static synchronized Worker getZeroWorker(){ return new WorkerZero(); }
public static synchronized WorkerSystem getSystemWorker(String serverName){
return systemLogWorkerMap.get(serverName);
}
private static Worker validateConsistancy(Worker worker, String server, String channel){ // synchronized?
if (worker.isConsistent()){
return worker;
}
System.out.println("BotDriver->validateConstancy(): Unable to use "
+worker.getClass().getSimpleName()+" for "+server+"/"+channel
+". Using ZeroWorker instead.");
return new WorkerZero();
}
}

View file

@ -0,0 +1,24 @@
package InnaIrcBot.logging;
import java.util.ArrayList;
import java.util.List;
public class SupportedLogDrivers{
public static final String files = "files";
public static final String sqlite = "sqlite";
public static final String mongodb = "mongodb";
public static final String zero = "zero";
private static final List<String> supportedLogDrivers = new ArrayList<>();
static {
supportedLogDrivers.add(files);
supportedLogDrivers.add(sqlite);
supportedLogDrivers.add(mongodb);
supportedLogDrivers.add(zero);
}
public static boolean contains(String driverName){
return supportedLogDrivers.contains(driverName);
}
}

View file

@ -1,4 +1,4 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
public interface Worker { public interface Worker {
boolean consistent = false; boolean consistent = false;

View file

@ -1,4 +1,4 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
@ -8,7 +8,7 @@ import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.regex.Pattern; import java.util.regex.Pattern;
public class BotFilesWorker implements Worker { public class WorkerFiles implements Worker {
private final String channel; private final String channel;
private String filePath; private String filePath;
private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("HH:mm:ss"); private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("HH:mm:ss");
@ -17,7 +17,7 @@ public class BotFilesWorker implements Worker {
private boolean consistent; private boolean consistent;
public BotFilesWorker(String server, String[] driverParameters, String channel){ public WorkerFiles(String server, String[] driverParameters, String channel){
this.channel = channel.replaceAll(File.separator, ","); this.channel = channel.replaceAll(File.separator, ",");
formatFilePath(server, driverParameters); formatFilePath(server, driverParameters);

View file

@ -1,4 +1,4 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
import com.mongodb.*; import com.mongodb.*;
import com.mongodb.client.MongoClient; import com.mongodb.client.MongoClient;
@ -8,6 +8,7 @@ import com.mongodb.client.MongoDatabase;
import com.mongodb.event.*; import com.mongodb.event.*;
import org.bson.Document; import org.bson.Document;
import java.io.Closeable;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -17,13 +18,13 @@ import java.util.concurrent.TimeUnit;
* For each channel we store collection that have name of the ircServer + chanelName. * For each channel we store collection that have name of the ircServer + chanelName.
* If user decides to use one MongoDB for various servers, he may use even one DB (declared in configuration file) and store collections in there. * If user decides to use one MongoDB for various servers, he may use even one DB (declared in configuration file) and store collections in there.
* **/ * **/
public class BotMongoWorker implements Worker { //TODO consider skipping checks if server already added. public class WorkerMongoDB implements Worker { //TODO consider skipping checks if server already added.
private final static Map<String, MongoClient> serversMap = Collections.synchronizedMap(new HashMap<>()); private final static Map<String, MongoClient> serversMap = Collections.synchronizedMap(new HashMap<>());
private final String server; private final String server;
private MongoCollection<Document> collection; private MongoCollection<Document> collection;
private boolean consistent; private boolean consistent;
public BotMongoWorker(String server, String[] driverParameters, String channel){ public WorkerMongoDB(String server, String[] driverParameters, String channel){
this.server = server; this.server = server;
if (driverParameters.length < 2) if (driverParameters.length < 2)
@ -129,17 +130,20 @@ public class BotMongoWorker implements Worker { //TODO consider sk
// no need to close() obviously // no need to close() obviously
} }
if (consistent){ setClosable();
ThingToCloseOnDie thing = () -> { }
if (serversMap.containsKey(server)) { private void setClosable(){
serversMap.get(server).close(); if (! consistent)
serversMap.remove(server); return;
}
};
BotDriver.getSystemWorker(server).registerInSystemWorker(thing); Closeable thing = () -> {
} if (serversMap.containsKey(server)) {
serversMap.get(server).close();
serversMap.remove(server);
}
};
LogDriver.getSystemWorker(server).registerInSystemWorker(thing);
} }
@Override @Override

View file

@ -1,4 +1,4 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
import org.sqlite.SQLiteConfig; import org.sqlite.SQLiteConfig;
import org.sqlite.SQLiteOpenMode; import org.sqlite.SQLiteOpenMode;
@ -6,7 +6,7 @@ import org.sqlite.SQLiteOpenMode;
import java.io.File; import java.io.File;
import java.sql.*; import java.sql.*;
public class BotSQLiteWorker implements Worker { public class WorkerSQLite implements Worker {
private Connection connection; private Connection connection;
private boolean consistent = false; private boolean consistent = false;
@ -16,7 +16,7 @@ public class BotSQLiteWorker implements Worker {
/** /**
* Don't even think of changing this balalaika. * Don't even think of changing this balalaika.
* */ * */
public BotSQLiteWorker(String server, String[] driverParameters, String channel){ // TODO: threads on SQLite level // remember: One file one DB public WorkerSQLite(String server, String[] driverParameters, String channel){ // TODO: threads on SQLite level // remember: One file one DB
this.ircServer = server; this.ircServer = server;
driverParameters[0] = driverParameters[0].trim(); driverParameters[0] = driverParameters[0].trim();
File dir = new File(driverParameters[0]); File dir = new File(driverParameters[0]);

View file

@ -1,22 +1,23 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
import java.io.Closeable;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
public class BotSystemWorker implements SystemWorker{ public class WorkerSystem{
private FileWriter fileWriter; private FileWriter fileWriter;
private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("HH:mm:ss"); private final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("HH:mm:ss");
private ThingToCloseOnDie thingToCloseOnDie; // call .die() method of this classes when this (system log class) dies. private Closeable thingToCloseOnDie; // call .close() method of this classes when this (system log class) dies.
private final String server; private final String server;
private boolean consistent = false; private boolean consistent = false;
public BotSystemWorker(String server, String appLogDir){ public WorkerSystem(String server, String appLogDir){
this.server = server; this.server = server;
if (appLogDir.isEmpty()) { if (appLogDir.isEmpty()) {
@ -53,7 +54,6 @@ public class BotSystemWorker implements SystemWorker{
return "["+ LocalTime.now().format(dateFormat)+"] "; return "["+ LocalTime.now().format(dateFormat)+"] ";
} }
@Override
public void logAdd(String event, String initiatorArg, String messageArg) { public void logAdd(String event, String initiatorArg, String messageArg) {
if (consistent) { if (consistent) {
try { try {
@ -69,19 +69,16 @@ public class BotSystemWorker implements SystemWorker{
System.out.println(genDate() + event + " " + initiatorArg + " " + messageArg + "\n"); System.out.println(genDate() + event + " " + initiatorArg + " " + messageArg + "\n");
} }
@Override public void registerInSystemWorker(Closeable thing){
public void registerInSystemWorker(ThingToCloseOnDie thing){
if (this.thingToCloseOnDie == null){ // only one needed if (this.thingToCloseOnDie == null){ // only one needed
this.thingToCloseOnDie = thing; this.thingToCloseOnDie = thing;
} }
} }
@Override
public void close() { public void close() {
if (thingToCloseOnDie != null)
thingToCloseOnDie.die();
try { try {
if (thingToCloseOnDie != null)
thingToCloseOnDie.close();
fileWriter.close(); fileWriter.close();
} }
catch (IOException | NullPointerException ignore){} catch (IOException | NullPointerException ignore){}

View file

@ -1,6 +1,6 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
public class BotZeroWorker implements Worker{ public class WorkerZero implements Worker{
@Override @Override
public boolean isConsistent() {return true;} public boolean isConsistent() {return true;}

View file

@ -1,74 +0,0 @@
package Temporary;
import InnaIrcBot.LogDriver.BotDriver;
import InnaIrcBot.LogDriver.Worker;
public class DriverTestMongo {
public static void main(String[] args){
if (BotDriver.setLogDriver("irc.tomsk.net", "MongoDB", new String[]{"192.168.1.186:27017",
"irc",
"loper",
"password"},
"/tmp/appLogs/"))
System.out.println("DRVT_Mongo:Successful driver initiation");
else {
System.out.println("DRVT_Mongo:Failed driver initiation");
return;
}
Worker fw1 = BotDriver.getWorker("irc.tomsk.net","system");
Worker fw2 = BotDriver.getWorker("irc.tomsk.net","#main");
Worker fw3 = BotDriver.getWorker("irc.tomsk.net","#lpr");
if ((fw1 !=null) && (fw2 !=null) && (fw3 !=null)){
System.out.println("DRVT_Mongo:LogFile1: "+fw1.isConsistent());
System.out.println("DRVT_Mongo:LogFile2: "+fw2.isConsistent());
System.out.println("DRVT_Mongo:LogFile3: "+fw3.isConsistent());
boolean res;
res = fw1.logAdd("JOIN", "de_su!loper@desktop.lan", "message1");
System.out.println("DRVT_Mongo:fw1 exec result: "+res);
res = fw1.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": some text here");
System.out.println("DRVT_Mongo:fw1 exec result: "+res);
res = fw1.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": more random tests");
System.out.println("DRVT_Mongo:fw1 exec result: "+res);
res = fw1.logAdd("NICK", "de_su!loper@desktop.lan", "developer_su");
System.out.println("DRVT_Mongo:fw1 exec result: "+res);
res = fw1.logAdd("MODE", "de_su!loper@desktop.lan", "+b username");
System.out.println("DRVT_Mongo:fw1 exec result: "+res);
res = fw1.logAdd("PART", "de_su!loper@desktop.lan", "#chan1");
System.out.println("DRVT_Mongo:fw1 exec result: "+res);
res = fw2.logAdd("JOIN", "de_su!loper@desktop.lan", "message2");
System.out.println("DRVT_Mongo:fw2 exec result: "+res);
res = fw2.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": some text here");
System.out.println("DRVT_Mongo:fw2 exec result: "+res);
res = fw2.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": more random tests");
System.out.println("DRVT_Mongo:fw2 exec result: "+res);
res = fw2.logAdd("NICK", "de_su!loper@desktop.lan", "developer_su");
System.out.println("DRVT_Mongo:fw2 exec result: "+res);
res = fw2.logAdd("MODE", "de_su!loper@desktop.lan", "+b username");
System.out.println("DRVT_Mongo:fw2 exec result: "+res);
res = fw2.logAdd("PART", "de_su!loper@desktop.lan", "#chan2");
System.out.println("DRVT_Mongo:fw2 exec result: "+res);
res = fw3.logAdd("JOIN", "de_su!loper@desktop.lan", "message3");
System.out.println("DRVT_Mongo:fw3 exec result: "+res);
res = fw3.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": some text here");
System.out.println("DRVT_Mongo:fw3 exec result: "+res);
res = fw3.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": more random tests");
System.out.println("DRVT_Mongo:fw3 exec result: "+res);
res = fw3.logAdd("NICK", "de_su!loper@desktop.lan", "developer_su");
System.out.println("DRVT_Mongo:fw3 exec result: "+res);
res = fw3.logAdd("MODE", "de_su!loper@desktop.lan", "+b username");
System.out.println("DRVT_Mongo:fw3 exec result: "+res);
res = fw3.logAdd("PART", "de_su!loper@desktop.lan", "#chan3");
System.out.println("DRVT_Mongo:fw3 exec result: "+res);
fw1.close();
fw2.close();
fw3.close();
}
}
}

View file

@ -1,31 +0,0 @@
package Temporary;
import InnaIrcBot.config.ConfigurationFile;
public class StorageFileTest {
static public void main(String[] args){
ConfigurationFile config = new ConfigurationFile(
"",
0,
"",
null,
"",
"",
"",
"",
"",
"",
true,
"",
new String[]{null},
"",
"",
""
);
System.out.println(config.getLogDriver().isEmpty());
System.out.println(config.getLogDriverParameters().length);
}
}

View file

@ -1,9 +0,0 @@
package Temporary;
public class StorageReaderTest {
public static void main(String[] args){
// StorageReader.readConfig("/home/loper/bot.config");
// StorageFile storageFile = StorageReader.getConfig();
// System.out.println(storageFile.getLogDriver() == null);
}
}

View file

@ -0,0 +1,96 @@
package InnaIrcBot.config;
import InnaIrcBot.logging.SupportedLogDrivers;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class ConfigurationFileTest {
ConfigurationFile config;
ConfigurationFileTest(){
config = new ConfigurationFile(
null,
-100,
null,
null,
null,
null,
null,
null,
null,
null,
true,
null,
new String[]{null},
null,
null,
null
);
}
@Test
void getServerName() {
}
@Test
void getServerPort() {
}
@Test
void getServerPass() {
}
@Test
void getChannels() {
}
@Test
void getUserNick() {
}
@Test
void getUserIdent() {
}
@Test
void getUserRealName() {
}
@Test
void getUserNickPass() {
}
@Test
void getUserNickAuthStyle() {
}
@Test
void getUserMode() {
}
@Test
void getRejoinOnKick() {
}
@Test
void getLogDriverConfiguration() {
assertEquals(config.getLogDriverConfiguration().getName(), SupportedLogDrivers.zero);
}
@Test
void getBotAdministratorPassword() {
}
@Test
void getChanelConfigurationsPath() {
}
@Test
void getApplicationLogDir() {
}
@Test
void setUserNickAuthStyle() {
}
}

View file

@ -1,5 +1,7 @@
package InnaIrcBot.LogDriver; package InnaIrcBot.logging;
import InnaIrcBot.config.LogDriverConfiguration;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -9,13 +11,14 @@ import org.junit.jupiter.api.io.TempDir;
import java.nio.file.Path; import java.nio.file.Path;
class BotDriverTest { class LogDriverTest {
@TempDir @TempDir
Path mainLogsDir, Path mainLogsDir,
mainSQLiteLogsDir; mainSQLiteLogsDir;
private static final String serverNameFiles = "irc.example.com"; private static final String serverNameFiles = "files.example.com";
private static final String serverNameSQLite = "irc2.example.com"; private static final String serverNameSQLite = "sqlite.example.com";
private static final String serverNameMongoDB = "mongo.example.com";
private Worker fw1; private Worker fw1;
private Worker fw2; private Worker fw2;
private Worker fw3; private Worker fw3;
@ -23,55 +26,66 @@ class BotDriverTest {
@DisplayName("BotDriver: test files driver") @DisplayName("BotDriver: test files driver")
@Test @Test
void driverFilesTest() { void driverFilesTest() {
assertTrue(this::initializeFilesLogDriver); initializeFilesLogDriver();
createWorkersForFiles(); createWorkers(serverNameFiles);
checkConsistency(); checkConsistency();
checkFilesWorkers(); checkFilesWorkers();
validateDriver(); validateDriver();
checkFilesWorkers(); checkFilesWorkers();
close(); close();
} }
private void createWorkersForFiles(){ void checkFilesWorkers(){
fw1 = BotDriver.getWorker(serverNameFiles,"system"); assertTrue(fw1 instanceof WorkerFiles);
fw2 = BotDriver.getWorker(serverNameFiles,"#main"); assertTrue(fw2 instanceof WorkerFiles);
fw3 = BotDriver.getWorker(serverNameFiles,"#lpr"); assertTrue(fw3 instanceof WorkerFiles);
} }
@DisplayName("BotDriver: test SQLite driver") @DisplayName("BotDriver: test SQLite driver")
@Test @Test
void driverSQLiteTest() { void driverSQLiteTest() {
assertTrue(this::initializeSQLiteLogDriver); initializeSQLiteLogDriver();
createWorkersForSQLite(); createWorkers(serverNameSQLite);
checkConsistency(); checkConsistency();
checkSQLiteWorkers(); checkSQLiteWorkers();
validateDriver(); validateDriver();
checkSQLiteWorkers(); checkSQLiteWorkers();
close(); close();
} }
private void createWorkersForSQLite(){ void checkSQLiteWorkers(){
fw1 = BotDriver.getWorker(serverNameSQLite,"system"); assertTrue(fw1 instanceof WorkerSQLite);
fw2 = BotDriver.getWorker(serverNameSQLite,"#main"); assertTrue(fw2 instanceof WorkerSQLite);
fw3 = BotDriver.getWorker(serverNameSQLite,"#lpr"); assertTrue(fw3 instanceof WorkerSQLite);
} }
@Disabled("MongoDB connection/configuration example. Requires real MongdDB instance created & configured")
@DisplayName("BotDriver: test MongoDB driver")
@Test
void driverMongoTest() {
initializeMongoDBLogDriver();
createWorkers(serverNameMongoDB);
checkConsistency();
checkMongoDBWorkers();
validateDriver();
checkMongoDBWorkers();
close();
}
void checkMongoDBWorkers(){
assertTrue(fw1 instanceof WorkerMongoDB);
assertTrue(fw2 instanceof WorkerMongoDB);
assertTrue(fw3 instanceof WorkerMongoDB);
}
private void createWorkers(String server){
fw1 = LogDriver.getWorker(server,"system");
fw2 = LogDriver.getWorker(server,"#main");
fw3 = LogDriver.getWorker(server,"#lpr");
}
void checkConsistency(){ void checkConsistency(){
assertTrue(fw1.isConsistent()); assertTrue(fw1.isConsistent());
assertTrue(fw2.isConsistent()); assertTrue(fw2.isConsistent());
assertTrue(fw3.isConsistent()); assertTrue(fw3.isConsistent());
} }
void checkFilesWorkers(){
assertTrue(fw1 instanceof BotFilesWorker);
assertTrue(fw2 instanceof BotFilesWorker);
assertTrue(fw3 instanceof BotFilesWorker);
}
void checkSQLiteWorkers(){
assertTrue(fw1 instanceof BotSQLiteWorker);
assertTrue(fw2 instanceof BotSQLiteWorker);
assertTrue(fw3 instanceof BotSQLiteWorker);
}
void validateDriver(){ void validateDriver(){
assertTrue(fw1.logAdd("JOIN", "de_su!loper@desktop.lan", "message1")); assertTrue(fw1.logAdd("JOIN", "de_su!loper@desktop.lan", "message1"));
assertTrue(fw1.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": some text here")); assertTrue(fw1.logAdd("PRIVMSG", "de_su!loper@desktop.lan", ": some text here"));
@ -95,12 +109,21 @@ class BotDriverTest {
assertTrue(fw3.logAdd("PART", "de_su!loper@desktop.lan", "#chan3")); assertTrue(fw3.logAdd("PART", "de_su!loper@desktop.lan", "#chan3"));
} }
private boolean initializeFilesLogDriver(){ private void initializeFilesLogDriver(){
return BotDriver.setLogDriver(serverNameFiles, "files", new String[]{mainLogsDir.toString()}, ""); LogDriver.setLogDriver(serverNameFiles, new LogDriverConfiguration("FileS", new String[]{mainLogsDir.toString()}), "");
} }
private boolean initializeSQLiteLogDriver(){ private void initializeSQLiteLogDriver(){
return BotDriver.setLogDriver(serverNameSQLite, "sqlite", new String[]{mainSQLiteLogsDir.toString()}, ""); LogDriver.setLogDriver(serverNameSQLite, new LogDriverConfiguration("SQliTe", new String[]{mainSQLiteLogsDir.toString()}), "");
}
private void initializeMongoDBLogDriver(){
String[] params = new String[]{"192.168.1.186:27017",
"irc",
"loper",
"password"};
LogDriver.setLogDriver("irc.tomsk.net",new LogDriverConfiguration("MongoDB", params),"");
} }
private void close(){ private void close(){