From c1299465d11fac0e45e662d33a856ac90ccc1f6c Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:08:48 -0800 Subject: [PATCH 01/11] Added Spring Boot --- build.gradle | 2 ++ gradle.lockfile | 40 +++++++++++++++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index adc41cb..0e6e69b 100644 --- a/build.gradle +++ b/build.gradle @@ -39,6 +39,8 @@ dependencies { exclude module: 'opus-java' } + implementation 'org.springframework.boot:spring-boot-starter-web:3.0.2' + implementation 'me.xdrop:fuzzywuzzy:1.4.0' implementation 'org.postgresql:postgresql:42.5.1' diff --git a/gradle.lockfile b/gradle.lockfile index 1d3ff98..81f672a 100644 --- a/gradle.lockfile +++ b/gradle.lockfile @@ -1,18 +1,31 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -com.fasterxml.jackson.core:jackson-annotations:2.13.2=runtimeClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-core:2.13.2=runtimeClasspath,testRuntimeClasspath -com.fasterxml.jackson.core:jackson-databind:2.13.2.2=runtimeClasspath,testRuntimeClasspath -com.fasterxml.jackson:jackson-bom:2.13.2=runtimeClasspath,testRuntimeClasspath +ch.qos.logback:logback-classic:1.4.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +ch.qos.logback:logback-core:1.4.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-core:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +com.fasterxml.jackson:jackson-bom:2.14.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.neovisionaries:nv-websocket-client:2.14=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.squareup.okhttp3:okhttp:4.9.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath com.squareup.okio:okio:2.8.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath io.github.cdimascio:dotenv-java:2.3.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-commons:1.10.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +io.micrometer:micrometer-observation:1.10.3=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath me.xdrop:fuzzywuzzy:1.4.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath net.dv8tion:JDA:5.0.0-beta.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath net.sf.trove4j:trove4j:3.0.3=runtimeClasspath,testRuntimeClasspath org.apache.commons:commons-collections4:4.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.logging.log4j:log4j-api:2.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.logging.log4j:log4j-to-slf4j:2.19.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-core:10.1.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-el:10.1.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.apache.tomcat.embed:tomcat-embed-websocket:10.1.5=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath org.checkerframework:checker-qual:3.5.0=runtimeClasspath,testRuntimeClasspath org.jetbrains.kotlin:kotlin-stdlib-common:1.4.10=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath @@ -25,6 +38,23 @@ org.junit.platform:junit-platform-engine:1.9.0=testRuntimeClasspath org.junit:junit-bom:5.9.0=testCompileClasspath,testRuntimeClasspath org.opentest4j:opentest4j:1.2.0=testCompileClasspath,testRuntimeClasspath org.postgresql:postgresql:42.5.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath -org.slf4j:slf4j-api:2.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.slf4j:jul-to-slf4j:2.0.6=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.slf4j:slf4j-api:2.0.6=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath org.slf4j:slf4j-simple:2.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-autoconfigure:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-json:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-logging:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-tomcat:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter-web:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot-starter:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework.boot:spring-boot:3.0.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-aop:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-beans:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-context:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-core:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-expression:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-jcl:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-web:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.springframework:spring-webmvc:6.0.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath +org.yaml:snakeyaml:1.33=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath empty=annotationProcessor,shadow,testAnnotationProcessor From 02c15f24ef19263cb8f06795f729b1ea2cbc3d90 Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:10:34 -0800 Subject: [PATCH 02/11] Added template controller implementation --- .../java/com/acmcsuf/triggers/BotController.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/com/acmcsuf/triggers/BotController.java diff --git a/src/main/java/com/acmcsuf/triggers/BotController.java b/src/main/java/com/acmcsuf/triggers/BotController.java new file mode 100644 index 0000000..faeca0d --- /dev/null +++ b/src/main/java/com/acmcsuf/triggers/BotController.java @@ -0,0 +1,13 @@ +package com.acmcsuf.triggers; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class BotController { + + @GetMapping("/api/ping") + public String ping() { + return "Hello, world!"; + } + +} \ No newline at end of file From 351838692a3f70b108a82bb7b1f7a12a8d9ab993 Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:15:48 -0800 Subject: [PATCH 03/11] Added annotations and Spring launch function --- src/main/java/com/acmcsuf/triggers/Bot.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/acmcsuf/triggers/Bot.java b/src/main/java/com/acmcsuf/triggers/Bot.java index 8d5350e..aa7c17d 100644 --- a/src/main/java/com/acmcsuf/triggers/Bot.java +++ b/src/main/java/com/acmcsuf/triggers/Bot.java @@ -15,6 +15,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication public class Bot { @@ -71,5 +75,7 @@ public static void main( String[] args ) throws InterruptedException log.error( "Failed to initialize database" ); e.printStackTrace(); } + + SpringApplication.run(BotController.class, args); } } \ No newline at end of file From 186ad998360b8aec41a5c487de9c3536f5998af6 Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:20:06 -0800 Subject: [PATCH 04/11] Added sync endpoint --- .../java/com/acmcsuf/triggers/BotController.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/java/com/acmcsuf/triggers/BotController.java b/src/main/java/com/acmcsuf/triggers/BotController.java index faeca0d..7a9f42b 100644 --- a/src/main/java/com/acmcsuf/triggers/BotController.java +++ b/src/main/java/com/acmcsuf/triggers/BotController.java @@ -1,5 +1,9 @@ package com.acmcsuf.triggers; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController @@ -9,5 +13,13 @@ public class BotController { public String ping() { return "Hello, world!"; } + + @PostMapping("/api/sync") + public ResponseEntity sync(@RequestParam("user_id") String userId) { + + // TODO: Add sync logic here + + return new ResponseEntity<>("Data synced successfully for user_id: " + userId, HttpStatus.OK); + } } \ No newline at end of file From 44e7c3d3843e064ad6da673a057760472840cdba Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:24:58 -0800 Subject: [PATCH 05/11] Added log message for Spring launch --- src/main/java/com/acmcsuf/triggers/Bot.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/acmcsuf/triggers/Bot.java b/src/main/java/com/acmcsuf/triggers/Bot.java index aa7c17d..534d903 100644 --- a/src/main/java/com/acmcsuf/triggers/Bot.java +++ b/src/main/java/com/acmcsuf/triggers/Bot.java @@ -77,5 +77,7 @@ public static void main( String[] args ) throws InterruptedException } SpringApplication.run(BotController.class, args); + log.info("Spring Boot application started."); + } } \ No newline at end of file From 1a3f0c8e329b1e566c79a14fc6a5f19fab40caf0 Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:51:31 -0800 Subject: [PATCH 06/11] Added new overloaded syncUserData() fuctions --- .../java/com/acmcsuf/triggers/Database.java | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/main/java/com/acmcsuf/triggers/Database.java b/src/main/java/com/acmcsuf/triggers/Database.java index 338df37..9770bac 100644 --- a/src/main/java/com/acmcsuf/triggers/Database.java +++ b/src/main/java/com/acmcsuf/triggers/Database.java @@ -373,6 +373,57 @@ public static void syncUserData( Member member, HashMap> triggerMap, + HashMap triggerToggle ) throws SQLException + { + String sql = String.format( """ + SELECT * FROM triggers + WHERE user_id = %s;""", userID ); + + try ( Connection conn = getConnect() ) + { + ResultSet set = conn.createStatement().executeQuery( sql ); + + if ( set.next() ) + { + insertData( triggerMap, triggerToggle, userID, set ); + } + } + } + + /** + * Sync member's in-memory trigger with database + * + * @param userID Event member user ID + * @param member Event member + * @param triggerMap In-memory trigger map + * @param triggerToggle In-memory trigger toggle map + * @throws SQLException On failure to interact with database + */ + public static void syncUserData( Connection connection, String userID, + HashMap> triggerMap, + HashMap triggerToggle ) throws SQLException + { + String sql = String.format( """ + SELECT * FROM triggers + WHERE user_id = %s;""", userID ); + + ResultSet set = connection.createStatement().executeQuery( sql ); + + if ( set.next() ) + { + insertData( triggerMap, triggerToggle, userID, set ); + } + } + /** * Sync member's in-memory trigger with database * From 7bb3824d036ed56e2c3c15bd167268affe3fb295 Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:55:06 -0800 Subject: [PATCH 07/11] Made maps public static --- src/main/java/com/acmcsuf/triggers/Trigger.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/acmcsuf/triggers/Trigger.java b/src/main/java/com/acmcsuf/triggers/Trigger.java index 8490561..82ee471 100644 --- a/src/main/java/com/acmcsuf/triggers/Trigger.java +++ b/src/main/java/com/acmcsuf/triggers/Trigger.java @@ -43,10 +43,10 @@ public Trigger( List authorizedRoleIDs ) List authorizedRoleIDs; // Discord member ID : Set of trigger phrases - HashMap> triggerMap = new HashMap<>(); + public static HashMap> triggerMap = new HashMap<>(); // Discord member ID : Trigger Activation (true = activated, false = deactivated) - HashMap triggerToggle = new HashMap<>(); + public static HashMap triggerToggle = new HashMap<>(); int min = 0; int max = 5; From 8a63bb6be6e2476e6e62c53e66296cec3172195d Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:55:39 -0800 Subject: [PATCH 08/11] Added more TODOs, added basic sync --- .../java/com/acmcsuf/triggers/BotController.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/acmcsuf/triggers/BotController.java b/src/main/java/com/acmcsuf/triggers/BotController.java index 7a9f42b..798d0e5 100644 --- a/src/main/java/com/acmcsuf/triggers/BotController.java +++ b/src/main/java/com/acmcsuf/triggers/BotController.java @@ -1,4 +1,6 @@ package com.acmcsuf.triggers; +import java.sql.SQLException; + import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -17,7 +19,17 @@ public String ping() { @PostMapping("/api/sync") public ResponseEntity sync(@RequestParam("user_id") String userId) { - // TODO: Add sync logic here + // TODO: Add authentication process (JWT?) + + // TODO: Add validation for user_id + + // Sync data from database + try { + Database.syncUserData(userId, Trigger.triggerMap, Trigger.triggerToggle); + } catch (SQLException e) { + e.printStackTrace(); + return new ResponseEntity<>("Error syncing data for user_id: " + userId, HttpStatus.INTERNAL_SERVER_ERROR); + } return new ResponseEntity<>("Data synced successfully for user_id: " + userId, HttpStatus.OK); } From a2c72b0d13f91a4bab9448291d70ddec06aa55eb Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:58:51 -0800 Subject: [PATCH 09/11] Added overloaded appendPhrase --- .../java/com/acmcsuf/triggers/Database.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/main/java/com/acmcsuf/triggers/Database.java b/src/main/java/com/acmcsuf/triggers/Database.java index 9770bac..541c6be 100644 --- a/src/main/java/com/acmcsuf/triggers/Database.java +++ b/src/main/java/com/acmcsuf/triggers/Database.java @@ -108,6 +108,50 @@ public static void appendPhrase( Member member, String phrase, Connection connec } } + /** + * Appends trigger phrase + * + *

+ * Appends new phrase to user's trigger list if it is not already in the list and syncs with database afterwards + *

+ * + * @param userID Event member user ID + * @param phrase Phrase to add + * @param connection Connection object + * @param triggerMap Map of user IDs to trigger phrases + * @param triggerToggle Map of user IDs to trigger toggle + * @throws SQLException On failure to interact with database + */ + public static void appendPhrase( String userID, String phrase, Connection connection, + HashMap> triggerMap, + HashMap triggerToggle ) throws SQLException + { + + String sql = """ + UPDATE triggers + SET phrase = array_append(phrase, ?::text) + WHERE user_id =""" + userID; + + try + { + PreparedStatement preparedStatement = connection.prepareStatement( sql ); + preparedStatement.setString( 1, phrase ); + preparedStatement.executeUpdate(); + } + catch ( PSQLException e ) + { + log.error( "Error appending phrase to database", e ); + } + try + { + syncUserData( connection, userID, triggerMap, triggerToggle ); + } + catch ( PSQLException e ) + { + log.error( "Error syncing user data", e ); + } + } + /** * Deletes trigger phrase * From 8d914a8596a8255a2e930be23374e33aa2db1abf Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 02:59:30 -0800 Subject: [PATCH 10/11] Added overloaded deletePhrase() --- .../java/com/acmcsuf/triggers/Database.java | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/main/java/com/acmcsuf/triggers/Database.java b/src/main/java/com/acmcsuf/triggers/Database.java index 541c6be..c2c3c29 100644 --- a/src/main/java/com/acmcsuf/triggers/Database.java +++ b/src/main/java/com/acmcsuf/triggers/Database.java @@ -152,6 +152,48 @@ public static void appendPhrase( String userID, String phrase, Connection connec } } + /** + * Deletes trigger phrase + * + *

+ * Deletes phrase from user's trigger list and syncs with database afterwards + *

+ * + * @param userID Event member user ID + * @param phrase Phrase to delete + * @throws SQLException On failure to interact with database + */ + public static void deletePhrase( String userID, String phrase, + HashMap> triggerMap, + HashMap triggerToggle ) throws SQLException + { + + String sql = """ + UPDATE triggers + SET phrase = array_remove(phrase, ?::text) + WHERE user_id =""" + userID; + + try ( Connection conn = getConnect() ) + { + PreparedStatement preparedStatement = conn.prepareStatement( sql ); + preparedStatement.setString( 1, phrase ); + preparedStatement.executeUpdate(); + + try + { + syncUserData( conn, userID, triggerMap, triggerToggle ); + } + catch ( PSQLException e ) + { + log.error( "Error syncing user data", e ); + } + } + catch ( PSQLException e ) + { + log.error( "Error deleting phrase from database", e ); + } + } + /** * Deletes trigger phrase * From 3fb90bc7bd70c464e06ba74b320914e96dcabbbb Mon Sep 17 00:00:00 2001 From: Joel Rico Date: Mon, 6 Feb 2023 03:00:28 -0800 Subject: [PATCH 11/11] Moved TODO --- src/main/java/com/acmcsuf/triggers/BotController.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/acmcsuf/triggers/BotController.java b/src/main/java/com/acmcsuf/triggers/BotController.java index 798d0e5..9087e9f 100644 --- a/src/main/java/com/acmcsuf/triggers/BotController.java +++ b/src/main/java/com/acmcsuf/triggers/BotController.java @@ -10,6 +10,8 @@ @RestController public class BotController { + + // TODO: Add authentication process (JWT?) @GetMapping("/api/ping") public String ping() { @@ -19,10 +21,6 @@ public String ping() { @PostMapping("/api/sync") public ResponseEntity sync(@RequestParam("user_id") String userId) { - // TODO: Add authentication process (JWT?) - - // TODO: Add validation for user_id - // Sync data from database try { Database.syncUserData(userId, Trigger.triggerMap, Trigger.triggerToggle);