From a39479c0bd7e0230d18abee8216a5000b355e296 Mon Sep 17 00:00:00 2001
From: io42630 <ivan@olexyn.com>
Date: Wed, 26 Mar 2025 10:49:25 +0100
Subject: [PATCH] make boot/rest driven

---
 README.md                                     | 17 ++++----
 pom.xml                                       | 36 ++++++++++++++++
 src/main/java/com/olexyn/ensync/MainApp.java  | 38 ++++-------------
 .../com/olexyn/ensync/web/Controller.java     | 35 ++++++++++++++++
 .../com/olexyn/ensync/web/EnsyncService.java  | 41 +++++++++++++++++++
 5 files changed, 130 insertions(+), 37 deletions(-)
 create mode 100644 src/main/java/com/olexyn/ensync/web/Controller.java
 create mode 100644 src/main/java/com/olexyn/ensync/web/EnsyncService.java

diff --git a/README.md b/README.md
index fb0f7a3..0c334ff 100644
--- a/README.md
+++ b/README.md
@@ -97,18 +97,21 @@ Sync files across directories.
 
 #### Package Contents
 
-| Path         | Comment |
-|---------------|-------------|
-doc | Diagrams.
-src.com.olexyn.ensync.artifacts | Data Model: Maps, Directories, Files. 
-src.com.olexyn.ensync.Main          | Run from here.
-src.com.olexyn.ensync.Flow      | Flow of the synchronization.
-src.com.olexyn.ensync. | Low level helper methods.
+| Path                            | Comment                               |
+|---------------------------------|---------------------------------------|
+| doc                             | Diagrams.                             |
+| src.com.olexyn.ensync.artifacts | Data Model: Maps, Directories, Files. |
+| src.com.olexyn.ensync.Main      | Run from here.                        |
+| src.com.olexyn.ensync.Flow      | Flow of the synchronization.          |
+| src.com.olexyn.ensync.          | Low level helper methods.             |
 
 <br>
 
 ### TODO <a name="todo"></a> 
 
+
+- New routine:
+  - look to burns-mail on how to create a REST-driven APP 
 - Add tests.
 - Reduce disk access.
 - Add error handling. (i.e. if a web-directory is not available)
diff --git a/pom.xml b/pom.xml
index 03a88f8..8856828 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,11 @@
 <?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>
+    <parent>
+        <groupId>com.olexyn</groupId>
+        <artifactId>min-root-spring</artifactId>
+        <version>17.0.0</version>
+    </parent>
     <groupId>com.olexyn.ensync</groupId>
     <artifactId>ensync</artifactId>
     <version>0.1</version>
@@ -13,6 +18,8 @@
         <maven.compiler.source>18</maven.compiler.source>
         <maven.compiler.target>18</maven.compiler.target>
         <kotlin.version>1.6.20-RC2</kotlin.version>
+        <!-- used by the spring-boot-maven-plugin -->
+        <start-class>com.olexyn.ensync.MainApp</start-class>
     </properties>
     <dependencies>
         <dependency>
@@ -53,6 +60,28 @@
             <version>0.1.1</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-autoconfigure</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-test</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <!-- for some godforsaken reason this is required. -->
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+        </dependency>
     </dependencies>
     <build>
         <pluginManagement>
@@ -140,6 +169,13 @@
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>${start-class}</mainClass>
+                </configuration>
+            </plugin>
         </plugins>
     </build>
 </project>
diff --git a/src/main/java/com/olexyn/ensync/MainApp.java b/src/main/java/com/olexyn/ensync/MainApp.java
index 5f23cb5..c4967e4 100644
--- a/src/main/java/com/olexyn/ensync/MainApp.java
+++ b/src/main/java/com/olexyn/ensync/MainApp.java
@@ -1,40 +1,18 @@
 package com.olexyn.ensync;
 
-import com.olexyn.ensync.artifacts.DataRoot;
-import com.olexyn.ensync.artifacts.SyncBundle;
-import com.olexyn.ensync.lock.LockUtil;
-import com.olexyn.ensync.util.IgnoreUtil;
-import com.olexyn.min.log.LogU;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-import java.nio.file.Path;
-
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
 
+@SpringBootApplication
+@EnableAspectJAutoProxy(proxyTargetClass = true)
 public class MainApp {
 
-    final public static Flow FLOW = new Flow();
-
-    final private static Tools TOOLS = new Tools();
 
-    public static void main(String[] args) throws JSONException {
-        LogU.remake(null, "com.olexyn.ensync.", "[%1$tF %1$tT] [%2$-7s] [%3$-14s] %4$-180s [%5$s]\n");
 
-        var configPath = Path.of(System.getProperty("user.dir") + "/src/main/resources/config.json");
-        String configString = Tools.fileToString(LockUtil.lockFile(configPath).getFc());
-        JSONObject dataRoot = new JSONObject(configString).getJSONObject("dataRoot");
-        for (String bundleKey : dataRoot.keySet()) {
-            SyncBundle syncBundle = new SyncBundle(bundleKey);
-            dataRoot.getJSONArray(bundleKey).toList()
-                .forEach(
-                    directoryPath -> syncBundle.addDirectory(Path.of(directoryPath.toString()))
-                );
+    public static void main(String[] args) {
+        SpringApplication.run(MainApp.class, args);
+    }
 
-            DataRoot.get().put(bundleKey, syncBundle);
-        }
 
-        var ignorePath = Path.of(System.getProperty("user.dir") + "/src/main/resources/syncignore");
-        IgnoreUtil.IGNORE = Tools.fileToLines(LockUtil.lockFile(ignorePath).getFc());
-        FLOW.start();
-    }
 }
diff --git a/src/main/java/com/olexyn/ensync/web/Controller.java b/src/main/java/com/olexyn/ensync/web/Controller.java
new file mode 100644
index 0000000..009a8dc
--- /dev/null
+++ b/src/main/java/com/olexyn/ensync/web/Controller.java
@@ -0,0 +1,35 @@
+package com.olexyn.ensync.web;
+
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class Controller {
+
+    private final EnsyncService ensyncService;
+    
+    
+    @Autowired
+    public Controller(
+        EnsyncService ensyncService
+    ){
+        this.ensyncService = ensyncService;
+    }
+
+    @PostMapping("/ensync")
+    public ResponseEntity<String> triageUnsubscribable() {
+        try {
+            ensyncService.ensync();
+        } catch (Exception e) {
+            return ResponseEntity.badRequest().build();
+        }
+        return ResponseEntity.ok().build();
+    }
+
+
+
+
+}
diff --git a/src/main/java/com/olexyn/ensync/web/EnsyncService.java b/src/main/java/com/olexyn/ensync/web/EnsyncService.java
new file mode 100644
index 0000000..60643d5
--- /dev/null
+++ b/src/main/java/com/olexyn/ensync/web/EnsyncService.java
@@ -0,0 +1,41 @@
+package com.olexyn.ensync.web;
+
+import com.olexyn.ensync.Flow;
+import com.olexyn.ensync.Tools;
+import com.olexyn.ensync.artifacts.DataRoot;
+import com.olexyn.ensync.artifacts.SyncBundle;
+import com.olexyn.ensync.lock.LockUtil;
+import com.olexyn.ensync.util.IgnoreUtil;
+import com.olexyn.min.log.LogU;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.springframework.stereotype.Service;
+
+import java.nio.file.Path;
+
+@Service
+public class EnsyncService {
+
+    final public static Flow FLOW = new Flow();
+
+    public void ensync() throws JSONException {
+        LogU.remake(null, "com.olexyn.ensync.", "[%1$tF %1$tT] [%2$-7s] [%3$-14s] %4$-180s [%5$s]\n");
+
+        var configPath = Path.of(System.getProperty("user.dir") + "/src/main/resources/config.json");
+        String configString = Tools.fileToString(LockUtil.lockFile(configPath).getFc());
+        JSONObject dataRoot = new JSONObject(configString).getJSONObject("dataRoot");
+        for (String bundleKey : dataRoot.keySet()) {
+            SyncBundle syncBundle = new SyncBundle(bundleKey);
+            dataRoot.getJSONArray(bundleKey).toList()
+                    .forEach(
+                            directoryPath -> syncBundle.addDirectory(Path.of(directoryPath.toString()))
+                    );
+
+            DataRoot.get().put(bundleKey, syncBundle);
+        }
+
+        var ignorePath = Path.of(System.getProperty("user.dir") + "/src/main/resources/syncignore");
+        IgnoreUtil.IGNORE = Tools.fileToLines(LockUtil.lockFile(ignorePath).getFc());
+        FLOW.start();
+    }
+}