Browse Source

Handle event for fingerprint data for afis template extraction feature

Dr-Swopt 1 tuần trước cách đây
mục cha
commit
6a42047faf

+ 4 - 0
README.md

@@ -15,3 +15,7 @@ This is a simple Java project set up in **VS Code**.
    ```sh
    git clone <repo-url>
    cd <your-project-folder>
+
+### Notes
+This is a simple Maven Java TPC server that is written to handle just one client, which is the nestjs microservice TCP client. It's 
+not meant for heavy duty usage, but primarily just to compare fingerprint scans.

+ 52 - 16
pom.xml

@@ -2,23 +2,59 @@
          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>
+    <modelVersion>4.0.0</modelVersion>
 
-  <groupId>com.example</groupId>
-  <artifactId>tcp-nest-bridge</artifactId>
-  <version>1.0-SNAPSHOT</version>
+    <groupId>com.example</groupId>
+    <artifactId>tcp-nest-bridge</artifactId>
+    <version>1.0-SNAPSHOT</version>
 
-  <properties>
-    <!-- Specify the Java version Maven should use for compiling -->
-    <maven.compiler.source>21</maven.compiler.source>
-    <maven.compiler.target>21</maven.compiler.target>
-  </properties>
+    <properties>
+        <!-- Specify the Java version Maven should use for compiling -->
+        <maven.compiler.source>21</maven.compiler.source>
+        <maven.compiler.target>21</maven.compiler.target>
+    </properties>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.json</groupId>
-      <artifactId>json</artifactId>
-      <version>20231013</version>
-    </dependency>
-  </dependencies>
+    <dependencies>
+        <!-- JSON dependency -->
+        <dependency>
+            <groupId>org.json</groupId>
+            <artifactId>json</artifactId>
+            <version>20231013</version>
+        </dependency>
+
+        <!-- SourceAFIS dependency -->
+        <dependency>
+            <groupId>com.machinezoo.sourceafis</groupId>
+            <artifactId>sourceafis</artifactId>
+            <version>3.18.1</version>
+        </dependency>
+
+        <!-- pom.xml -->
+        <dependency>
+            <groupId>org.msgpack</groupId>
+            <artifactId>msgpack-core</artifactId>
+            <version>0.9.0</version>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>3.1.0</version>
+                <executions>
+                    <execution>
+                        <phase>compile</phase>  <!-- Ensure it's part of the compile phase -->
+                        <goals>
+                            <goal>java</goal>
+                        </goals>
+                        <configuration>
+                            <mainClass>com.example.Main</mainClass>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
 </project>

+ 9 - 30
src/main/java/com/example/ClientHandler.java

@@ -6,8 +6,6 @@ import java.io.InputStreamReader;
 import java.io.PrintWriter;
 import java.net.Socket;
 
-import org.json.JSONObject;
-
 public class ClientHandler implements Runnable {
 
     private final Socket socket;
@@ -31,9 +29,9 @@ public class ClientHandler implements Runnable {
             while ((rawMessage = in.readLine()) != null) {
                 System.out.println("📨 Received: " + rawMessage);
 
-                String response = handleEvent(rawMessage);
+                String response = EventHandler.handleEvent(rawMessage); // all fingerprint data goes through here
                 System.out.println("📤 Responding: " + response);
-                out.println(response);
+                out.println(response); // this is the part that is emits to the client
             }
 
             System.out.println("Client disconnected: " + socket.getInetAddress());
@@ -42,8 +40,12 @@ public class ClientHandler implements Runnable {
             System.err.println("Client handler error: " + e.getMessage());
         } finally {
             try {
-                if (in != null) in.close();
-                if (out != null) out.close();
+                if (in != null) {
+                    in.close();
+                }
+                if (out != null) {
+                    out.close();
+                }
                 socket.close();
             } catch (IOException e) {
                 System.err.println("Error closing client socket: " + e.getMessage());
@@ -51,27 +53,4 @@ public class ClientHandler implements Runnable {
         }
     }
 
-    private String handleEvent(String rawMessage) {
-        try {
-            JSONObject message = new JSONObject(rawMessage);
-
-            String pattern = message.optString("pattern", "unknown");
-            JSONObject data = message.optJSONObject("data");
-
-            // You could use pattern to route logic
-            String resultMessage = "Received pattern: " + pattern + ", data: " + (data != null ? data.toString() : "null");
-
-            // Build response
-            JSONObject response = new JSONObject();
-            response.put("pattern", pattern);
-            response.put("result", resultMessage);
-
-            return response.toString();
-
-        } catch (Exception e) {
-            JSONObject error = new JSONObject();
-            error.put("error", "Invalid message format: " + e.getMessage());
-            return error.toString();
-        }
-    }
-}
+}

+ 159 - 0
src/main/java/com/example/EventHandler.java

@@ -0,0 +1,159 @@
+package com.example;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.util.Base64;
+
+import javax.imageio.ImageIO;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import com.machinezoo.sourceafis.FingerprintImage;
+import com.machinezoo.sourceafis.FingerprintMatcher;
+import com.machinezoo.sourceafis.FingerprintTemplate;
+
+public class EventHandler {
+
+    private static final double MATCH_THRESHOLD = 40.0;
+
+    public static String handleEvent(String rawMessage) {
+        try {
+            System.err.println(rawMessage);
+    
+            JSONObject message = new JSONObject(rawMessage);
+    
+            String id = message.optString("id", "unknown");
+            String cmd = message.optString("cmd", "").toLowerCase();
+            String data = message.optString("data", null); // base64 string
+    
+            if (data == null) {
+                throw new IllegalArgumentException("Missing base64 data payload");
+            }
+    
+            switch (cmd) {
+                case "registration":
+                    return handleRegistration(id, data, message);
+                // case "verification":
+                //     return handleVerification(...);
+                case "extract template":
+                    return handleExtractTemplate(id, data);
+                default:
+                    JSONObject unknown = new JSONObject();
+                    unknown.put("id", id);
+                    unknown.put("message", "Unknown command: " + cmd);
+                    return unknown.toString();
+            }
+    
+        } catch (Exception e) {
+            JSONObject error = new JSONObject();
+            error.put("error", "Failed to process message: " + e.getMessage());
+            return error.toString();
+        }
+    }
+    
+
+    private static String handleRegistration(String id, String imageBase64, JSONObject message) {
+        try {
+            // Extract the fingerprint template array (fpTemplateArray) from the root-level message
+            JSONArray templateArray = message.optJSONArray("fpTemplateArray");
+    
+            if (imageBase64 == null || templateArray == null) {
+                throw new IllegalArgumentException("Missing image data or template array.");
+            }
+    
+            // Convert Base64 image to BufferedImage
+            byte[] imageBytes = Base64.getDecoder().decode(imageBase64);
+            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
+    
+            if (image == null) {
+                throw new IllegalArgumentException("Invalid image format.");
+            }
+    
+            // Create a fingerprint template from the image
+            FingerprintTemplate probeTemplate = new FingerprintTemplate(new FingerprintImage(imageBytes));
+    
+            // If the template array is empty, skip the matching logic
+            if (templateArray.isEmpty()) {
+                // No existing templates to compare with, proceed with registration of the new template
+                String newTemplateB64 = Base64.getEncoder().encodeToString(probeTemplate.toByteArray());
+    
+                JSONObject response = new JSONObject();
+                response.put("id", id);
+                response.put("message", "New fingerprint template constructed.");
+                response.put("data", newTemplateB64);
+                response.put("score", 100);
+                return response.toString();
+            }
+    
+            // Compare with existing templates (if any)
+            for (int i = 0; i < templateArray.length(); i++) {
+                String templateB64 = templateArray.getString(i);
+                byte[] templateBytes = Base64.getDecoder().decode(templateB64);
+                FingerprintTemplate candidate = new FingerprintTemplate(templateBytes);
+    
+                double score = new FingerprintMatcher(probeTemplate).match(candidate);
+                if (score >= MATCH_THRESHOLD) {
+                    JSONObject response = new JSONObject();
+                    response.put("id", id);
+                    response.put("message", "Fingerprint already registered.");
+                    response.put("score", score);
+                    response.put("data", JSONObject.NULL);
+                    return response.toString();
+                }
+            }
+    
+            // No match: register new
+            String newTemplateB64 = Base64.getEncoder().encodeToString(probeTemplate.toByteArray());
+    
+            JSONObject response = new JSONObject();
+            response.put("id", id);
+            response.put("message", "New fingerprint template constructed.");
+            response.put("data", newTemplateB64);
+            response.put("score", 100);
+            return response.toString();
+    
+        } catch (Exception e) {
+            JSONObject error = new JSONObject();
+            error.put("error", "Registration failed: " + e.getMessage());
+            return error.toString();
+        }
+    }
+    
+    
+
+    private static String handleVerification(JSONObject data) {
+        try {
+            // logic here
+        } catch (Exception e) {
+        }
+        return null;
+    }
+
+    public static String handleExtractTemplate(String id, String base64) {
+        try {
+            byte[] imageBytes = Base64.getDecoder().decode(base64);
+            BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
+    
+            if (image == null) {
+                throw new IllegalArgumentException("Invalid image data.");
+            }
+    
+            FingerprintTemplate template = new FingerprintTemplate(new FingerprintImage(imageBytes));
+    
+            JSONObject response = new JSONObject();
+            response.put("id", id);
+            response.put("message", "Fingerprint template successfully extracted.");
+            response.put("data", Base64.getEncoder().encodeToString(template.toByteArray())); // optional
+    
+            return response.toString();
+    
+        } catch (Exception e) {
+            JSONObject error = new JSONObject();
+            error.put("id", id);
+            error.put("error", "Template extraction failed: " + e.getMessage());
+            return error.toString();
+        }
+    }
+    
+}

+ 25 - 0
src/main/java/com/example/Models.java

@@ -0,0 +1,25 @@
+package com.example;
+
+import java.sql.Date;
+import java.util.List;
+
+public class Models {
+
+    public class FpVerificationPayload {
+        public String id;
+        public String cmd;
+        public Date date;
+        public Object data;
+        public String fpTemplate; // base64 string
+        public List<String> fpTemplateArray; // list of base64 strings
+        public String message;
+    }
+
+    public class FpVerificationResponse {
+        public String id;
+        public String message;
+        public String data;
+        public Double score;
+    }
+
+}

+ 5 - 1
target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst

@@ -1,4 +1,8 @@
-com\example\TCPServer.class
 com\example\Main.class
 com\example\ClientHandler.class
+com\example\EventHandler.class
+com\example\Models.class
+com\example\TCPServer.class
+com\example\Models$FpVerificationResponse.class
 com\example\TCPClient.class
+com\example\Models$FpVerificationPayload.class

+ 6 - 4
target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst

@@ -1,4 +1,6 @@
-E:\Task\Fingerprint\FingerprintVerificationJava\src\main\java\com\example\ClientHandler.java
-E:\Task\Fingerprint\FingerprintVerificationJava\src\main\java\com\example\Main.java
-E:\Task\Fingerprint\FingerprintVerificationJava\src\main\java\com\example\TCPClient.java
-E:\Task\Fingerprint\FingerprintVerificationJava\src\main\java\com\example\TCPServer.java
+E:\Task\Fingerprint\microservices\libs\java\FingerprintDataVerification\src\main\java\com\example\ClientHandler.java
+E:\Task\Fingerprint\microservices\libs\java\FingerprintDataVerification\src\main\java\com\example\EventHandler.java
+E:\Task\Fingerprint\microservices\libs\java\FingerprintDataVerification\src\main\java\com\example\Main.java
+E:\Task\Fingerprint\microservices\libs\java\FingerprintDataVerification\src\main\java\com\example\Models.java
+E:\Task\Fingerprint\microservices\libs\java\FingerprintDataVerification\src\main\java\com\example\TCPClient.java
+E:\Task\Fingerprint\microservices\libs\java\FingerprintDataVerification\src\main\java\com\example\TCPServer.java