Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update #88

Merged
merged 12 commits into from
Aug 12, 2024
1 change: 1 addition & 0 deletions src/main/java/com/toxicstoxm/LEDSuite/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static final class Config {
public static final String LOG_FILE_ENABLED = LOGGING_FILE_SECTION + SEPARATOR + "Enabled";
public static final String LOG_FILE_LOG_LEVEL_ALL = LOGGING_FILE_SECTION + SEPARATOR + "Log-Level-All";
public static final String LOG_FILE_MAX_FILES = LOGGING_FILE_SECTION + SEPARATOR + "Max-Files";
public static final String MAX_STACK_TRACES_CACHED = LOGGING_SECTION + SEPARATOR + "Max-Stack-Traces-Cached";

public static final String CHECK_IPV4 = NETWORK_SECTION + SEPARATOR + "Check-IPv4";
public static final String NETWORK_COMMUNICATION_CLOCK = PERIODIC_SECTION + SEPARATOR + "Network-Communication-Clock";
Expand Down
201 changes: 100 additions & 101 deletions src/main/java/com/toxicstoxm/LEDSuite/LEDSuite.java

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions src/main/java/com/toxicstoxm/LEDSuite/cache/Cache.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package com.toxicstoxm.LEDSuite.cache;

import com.toxicstoxm.LEDSuite.LEDSuite;
import lombok.NonNull;

import java.util.HashMap;

/**
* This is a wrapper of the standard HashMap implementation.
* <p>
* This class can be used instead of creating a lot of global variables. It allows for easy storage and retrieval of objects,
* with additional safety features such as automatic null-checks and class cast exception handling.
* </p>
*
* @implNote This class extends {@link HashMap} and overrides the {@code put} method to include a warning if a key
* already exists in the cache. It also includes a custom {@code get} method that performs type checking and
* handles potential {@link ClassCastException}s.
*
* @param <K> the type of keys maintained by this map
* @param <V> the type of mapped values
*/
public class Cache<K, V> extends HashMap<K, V> {

/**
* Associates the specified value with the specified key in this cache. If the cache previously contained a
* mapping for the key, the old value is replaced by the specified value.
* <p>
* If the key already exists in the cache, a warning is logged.
* </p>
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with {@code key}.)
*/
@Override
public V put(K key, V value) {
return put(key, value, false);
}

/**
* Associates the specified value with the specified key in this cache, with an option to suppress warnings.
* <p>
* If the cache previously contained a mapping for the key, the old value is replaced by the specified value.
* If the key already exists in the cache, a warning is logged unless the {@code suppressOverrideWarning} parameter is set to {@code true}.
* </p>
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @param suppressOverrideWarning if {@code true}, suppresses the warning when a key already exists in the cache
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
* (A {@code null} return can also indicate that the map
* previously associated {@code null} with {@code key}.)
*/
public V put(K key, V value, boolean suppressOverrideWarning) {
if (containsKey(key)) {
if (!suppressOverrideWarning) {
LEDSuite.logger.warn("Cache already contains object for key: '" + key + "'!");
}
}
return super.put(key, value);
}

/**
* Retrieves the value associated with the specified key and casts it to the desired type.
* <p>
* If the key does not exist or if the value cannot be cast to the desired type, {@code null} is returned,
* and a warning is logged in case of a {@link ClassCastException}.
* </p>
*
* @param <T> the type to which the value should be cast
* @param desiredType the {@link Class} object representing the desired type
* @param key the key whose associated value is to be returned
* @return the value mapped to the specified key cast to the desired type, or {@code null} if the key does not exist
* or if the cast fails
*/
public <T> T get(@NonNull Class<T> desiredType, @NonNull String key) {
if (!containsKey(key)) {
return null;
}
try {
return desiredType.cast(super.get(key));
} catch (ClassCastException e) {
LEDSuite.logger.warn("Failed to get cache for Key: '" + key + "' and type: '" + desiredType.getName() + "'!");
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,9 @@ public static void sendFile(String serverIP4, int serverPort, String fileToSendP
// loading the specified file to memory
File fileToSend = new File(fileToSendPath);
try {
// disabling periodic requests to prevent unwanted data injection
TimeManager.lock("keepalive");
TimeManager.lock("status");
// send a file upload request to the server
sendYAMLDefaultHost(
YAMLMessage.builder()
Expand All @@ -262,12 +265,18 @@ public static void sendFile(String serverIP4, int serverPort, String fileToSendP
.setObjectNewValue(String.valueOf(fileToSend.length()))
.build(),
success -> {
// if the request was successful, send the file to the server using the sendFile() method
if (success) {
if (!sendFile(serverIP4, serverPort, progressTracker, fileToSend)) {
LEDSuite.logger.error("Failed to send file '" + fileToSendPath + "' to server '" + serverIP4 + ":" + serverPort + "'!");
TimeManager.lock("mgr");
new LEDSuiteRunnable() {
@Override
public void run() {
// if the request was successful, send the file to the server using the sendFile() method
if (success) {
if (!sendFile(serverIP4, serverPort, progressTracker, fileToSend)) {
LEDSuite.logger.warn("Failed to send file '" + fileToSendPath + "' to server '" + serverIP4 + ":" + serverPort + "'!");
}
}
}
}
}.runTaskLaterAsynchronously(100);
}
);
} catch (YAMLSerializer.TODOException | ConfigurationException | YAMLSerializer.InvalidReplyTypeException |
Expand All @@ -276,7 +285,7 @@ public static void sendFile(String serverIP4, int serverPort, String fileToSendP
}
}

// send file to server using sockets
// send a file to server using sockets

/**
*
Expand Down Expand Up @@ -314,11 +323,6 @@ public static boolean sendFile(String serverIPv4, int serverPort, ProgressTracke

try {

// disabling periodic requests to prevent unwanted data injection
TimeManager.lock("keepalive");
TimeManager.lock("status");
TimeManager.lock("mgr");

// getting current socket from network handler
Socket socket = NetworkHandler.getServer();
LEDSuite.logger.verbose(id + "Successfully established connection!");
Expand Down Expand Up @@ -430,6 +434,7 @@ public static boolean sendFile(String serverIPv4, int serverPort, ProgressTracke
// calculating transferred size in MB
double temp1 = (double) transferredSize / (1024 * 1024);
mbTransferredSize = (double) Math.round(temp1 * 1000) / 1000;
out.flush();
}

// if the progress tracker object is not null and the upload has finished,
Expand All @@ -451,12 +456,11 @@ public static boolean sendFile(String serverIPv4, int serverPort, ProgressTracke
LEDSuite.logger.verbose(id + "Sending complete!");
} catch (IOException e) {
if (track) progressTracker.setError(true); // inform the progress tracker of the occurred error
LEDSuite.logger.error(id + "Error occurred! Transmission terminated!");
LEDSuite.logger.displayError(e);
LEDSuite.logger.warn(id + "Error occurred! Transmission terminated! " + LEDSuite.logger.getErrorMessage(e));
return false;
} catch (NetworkException e) {
if (track) progressTracker.setError(true); // inform the progress tracker of the occurred error
LEDSuite.logger.fatal(id + "Network error: " + e.getMessage());
LEDSuite.logger.warn(id + "Network error! " + LEDSuite.logger.getErrorMessage(e));
} finally {
// re enabling periodic requests
TimeManager.release("keepalive");
Expand Down Expand Up @@ -606,8 +610,7 @@ public static void init(SuccessCallback callback) throws NetworkException {
LEDSuite.logger.verbose("Successfully connected to server!");
} catch (IOException e) {
// if connection fails, inform the caller function using the callback
LEDSuite.logger.fatal("Failed to initialize connection to server! Error: " + e.getMessage());
LEDSuite.logger.displayError(e);
LEDSuite.logger.warn("Failed to initialize connection to server! " + LEDSuite.logger.getErrorMessage(e));
serverIsRebooting = false;
if (callback != null) callback.getResult(false);
return;
Expand All @@ -621,7 +624,6 @@ public static void init(SuccessCallback callback) throws NetworkException {
LEDSuite.logger.verbose("Network Handler: started network handle!");
}


// if manager is already running, cancel it
if (mgr != null) mgr.cancel();
long keepalive = 500;
Expand All @@ -638,7 +640,7 @@ public static void init(SuccessCallback callback) throws NetworkException {
@Override
public void run() {
if (!TimeManager.call("mgr")) return;
// check if keepalive needs to be sent
// check if keepalive needs to be sent
if (TimeManager.call("keepalive")) {
LEDSuite.logger.verbose("Sending keepalive");
try {
Expand Down Expand Up @@ -670,7 +672,7 @@ public void run() {
if (!networkQueue.isEmpty() && isConnected()) {
Map.Entry<Long, LEDSuiteRunnable> entry = networkQueue.firstEntry();
LEDSuite.logger.verbose("Handling request: " + entry.getKey());
entry.getValue().runTaskAsynchronously();
entry.getValue().runTask();
networkQueue.remove(entry.getKey());
}
}
Expand Down Expand Up @@ -750,8 +752,7 @@ public void run() {
}
}
} catch (Exception e) {
LEDSuite.logger.fatal("Network Handler: master listener: Error: " + e.getMessage());
LEDSuite.logger.displayError(e);
LEDSuite.logger.error("Network Handler: Error while running master listener! " + LEDSuite.logger.getErrorMessage(e));
}

}
Expand Down Expand Up @@ -818,8 +819,7 @@ public static void reboot() throws NetworkException {
if (!success) throw new NetworkException("connection failed");
});
} catch (NetworkException e) {
LEDSuite.logger.fatal("Network Handler: reboot failed!");
LEDSuite.logger.displayError(e);
LEDSuite.logger.warn("Network Handler: reboot failed! " + LEDSuite.logger.getErrorMessage(e));
throw new NetworkException("connection failed!");
}
}
Expand Down Expand Up @@ -885,7 +885,7 @@ public void onSettingChanged(Events.SettingChanged e) {
);
} catch (YAMLSerializer.TODOException | ConfigurationException |
YAMLSerializer.InvalidReplyTypeException | YAMLSerializer.InvalidPacketTypeException ex) {
LEDSuite.logger.error("Failed to send (1) settings change request!");
LEDSuite.logger.warn("Failed to send (1) settings change request!");
}
LEDSuite.logger.verbose("Successfully send (1) settings change request to server!");
}
Expand All @@ -907,7 +907,7 @@ public void onSettingsChanged(Events.SettingsChanged e) {
);
} catch (YAMLSerializer.TODOException | ConfigurationException |
YAMLSerializer.InvalidReplyTypeException | YAMLSerializer.InvalidPacketTypeException ex) {
LEDSuite.logger.error("Failed to send (" + changedSettings.size() +") settings change request!");
LEDSuite.logger.warn("Failed to send (" + changedSettings.size() +") settings change request!");
}
LEDSuite.logger.verbose("Successfully send (" + changedSettings.size() +") settings change request to server!");
}
Expand Down Expand Up @@ -1059,7 +1059,7 @@ public static boolean sendKeepalive(YAMLConfiguration yaml, boolean displayLog)
*/
public static void sendYAMLDefaultHost(YAMLConfiguration yaml) {
if (!sendYAML(LEDSuite.server_settings.getIPv4(), LEDSuite.server_settings.getPort(), yaml, null)) {
LEDSuite.logger.error("Failed to send YAML message to server! Callback = false | ReplyHandler = false");
LEDSuite.logger.warn("Failed to send YAML message to server!");
}
}

Expand All @@ -1075,7 +1075,7 @@ public static void sendYAMLDefaultHost(YAMLConfiguration yaml) {
*/
public static void sendYAMLDefaultHost(YAMLConfiguration yaml, FinishCallback callback) {
if (!sendYAML(LEDSuite.server_settings.getIPv4(), LEDSuite.server_settings.getPort(), yaml, callback)) {
LEDSuite.logger.error("Failed to send YAML message with callback to server! Callback = true | ReplyHandler = false");
LEDSuite.logger.warn("Failed to send YAML message to server!");
}
}

Expand All @@ -1092,7 +1092,7 @@ public static void sendYAMLDefaultHost(YAMLConfiguration yaml, FinishCallback ca
*/
public static void sendYAMLDefaultHost(YAMLConfiguration yaml, FinishCallback callback, LEDSuiteProcessor replyHandler) {
if (!sendYAML(LEDSuite.server_settings.getIPv4(), LEDSuite.server_settings.getPort(), yaml, callback, replyHandler)) {
LEDSuite.logger.error("Failed to send YAML message with to server! Callback = true | ReplyHandler = true");
LEDSuite.logger.warn("Failed to send YAML message to server!");
}
}

Expand Down Expand Up @@ -1144,8 +1144,7 @@ public static boolean sendYAML(String host, int port, YAMLConfiguration yaml, Fi
if (callback != null) callback.onFinish(true);
LEDSuite.logger.verbose("Successfully reconnected to previous server!");
} catch (NetworkException e) {
LEDSuite.logger.fatal(e.getMessage());
LEDSuite.logger.error("Reconnection attempt to previous server failed!");
LEDSuite.logger.warn("Reconnection attempt to previous server failed! " + LEDSuite.logger.getErrorMessage(e));
if (callback != null) callback.onFinish(false);
return false;
}
Expand Down Expand Up @@ -1178,7 +1177,7 @@ public void run() {
*/
private static void sendYAMLMessage(String serverIP4, int serverPort, YAMLConfiguration yaml, FinishCallback callback, LEDSuiteProcessor replyHandle) {
if (!sendYAMLMessage(serverIP4, serverPort, yaml, callback, replyHandle, true)) {
LEDSuite.logger.error("Failed to send YAML message to server!");
LEDSuite.logger.warn("Failed to send YAML message to server!");
}
}

Expand Down Expand Up @@ -1301,6 +1300,7 @@ private static boolean sendYAMLMessage(String serverIP4, int serverPort, YAMLCon
// sending yaml data to server
if (displayLog) LEDSuite.logger.verbose(id + "Transmitting data...");
out.write(bytes);
out.flush();
if (displayLog) LEDSuite.logger.verbose(id + "Successfully transmitted data to server!");

if (displayLog) {
Expand All @@ -1316,13 +1316,12 @@ private static boolean sendYAMLMessage(String serverIP4, int serverPort, YAMLCon
} catch (NetworkException ex) {
// if an error occurs, print an error message and give up
if (displayLog) {
LEDSuite.logger.error(id + "Error occurred! Transmission terminated!");
LEDSuite.logger.displayError(e);
LEDSuite.logger.warn(id + "Error occurred! Transmission terminated! " + LEDSuite.logger.getErrorMessage(e));
}
err = true;
}
} catch (NetworkException e) {
if (displayLog) LEDSuite.logger.fatal(id + "Network error: " + e.getMessage());
if (displayLog) LEDSuite.logger.warn(id + "Network error! " + LEDSuite.logger.getErrorMessage(e));
}
finally {
if (displayLog) LEDSuite.logger.verbose(id + "---------------------------------------------------------------");
Expand All @@ -1332,7 +1331,6 @@ private static boolean sendYAMLMessage(String serverIP4, int serverPort, YAMLCon
err = !err;
if (callb) callback.onFinish(err);
return err;

}
}

Expand Down
Loading
Loading