KevanSoon commited on
Commit
fc9a733
·
1 Parent(s): 0048178

added integration with frontend and python backend

Browse files
src/main/java/com/cs102/attendance/config/SecurityConfig.java ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ package com.cs102.attendance.config;
2
+
3
+ import org.springframework.context.annotation.Bean;
4
+ import org.springframework.context.annotation.Configuration;
5
+ import org.springframework.security.config.Customizer;
6
+ import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7
+ import org.springframework.security.web.SecurityFilterChain;
8
+
9
+ @Configuration
10
+ public class SecurityConfig {
11
+
12
+ @Bean
13
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
14
+ http
15
+ .csrf(csrf -> csrf.disable()) // Disable CSRF for simplicity
16
+ .authorizeHttpRequests(auth -> auth
17
+ .requestMatchers("/call-face-recognition").permitAll()
18
+ .anyRequest().authenticated()
19
+ )
20
+ .httpBasic(Customizer.withDefaults()); // or formLogin/custom config
21
+ return http.build();
22
+ }
23
+ }
src/main/java/com/cs102/attendance/controller/FastApiCallerController.java CHANGED
@@ -1,12 +1,15 @@
1
- // FastApiCallerController.java
2
  package com.cs102.attendance.controller;
3
 
4
- import org.springframework.web.bind.annotation.GetMapping;
 
 
5
  import org.springframework.web.bind.annotation.RestController;
 
6
 
7
  import com.cs102.attendance.service.FastApiCallerService;
8
 
9
  @RestController
 
10
  public class FastApiCallerController {
11
 
12
  private final FastApiCallerService fastApiCallerService;
@@ -15,13 +18,13 @@ public class FastApiCallerController {
15
  this.fastApiCallerService = fastApiCallerService;
16
  }
17
 
18
- @GetMapping("/call-face-recognition")
19
- public String callFaceRecognition() {
20
  try {
21
- return fastApiCallerService.callFaceRecognition();
22
  } catch (Exception e) {
23
  e.printStackTrace();
24
- return "Error calling face-recognition API";
25
  }
26
  }
27
  }
 
 
1
  package com.cs102.attendance.controller;
2
 
3
+ import org.springframework.web.bind.annotation.CrossOrigin;
4
+ import org.springframework.web.bind.annotation.PostMapping;
5
+ import org.springframework.web.bind.annotation.RequestParam;
6
  import org.springframework.web.bind.annotation.RestController;
7
+ import org.springframework.web.multipart.MultipartFile;
8
 
9
  import com.cs102.attendance.service.FastApiCallerService;
10
 
11
  @RestController
12
+ @CrossOrigin(origins = "https://cs-102-vert.vercel.app/")
13
  public class FastApiCallerController {
14
 
15
  private final FastApiCallerService fastApiCallerService;
 
18
  this.fastApiCallerService = fastApiCallerService;
19
  }
20
 
21
+ @PostMapping("/call-face-recognition")
22
+ public String callFaceRecognition(@RequestParam("image") MultipartFile imageFile) {
23
  try {
24
+ return fastApiCallerService.callFaceRecognitionWithImage(imageFile);
25
  } catch (Exception e) {
26
  e.printStackTrace();
27
+ return "Error processing image: " + e.getMessage();
28
  }
29
  }
30
  }
src/main/java/com/cs102/attendance/controller/HealthController.java CHANGED
@@ -1,49 +1,49 @@
1
- package com.cs102.attendance.controller;
2
 
3
- import org.springframework.beans.factory.annotation.Autowired;
4
- import org.springframework.http.ResponseEntity;
5
- import org.springframework.web.bind.annotation.GetMapping;
6
- import org.springframework.web.bind.annotation.RequestMapping;
7
- import org.springframework.web.bind.annotation.RestController;
8
 
9
- import javax.sql.DataSource;
10
- import java.sql.Connection;
11
- import java.sql.SQLException;
12
- import java.util.HashMap;
13
- import java.util.Map;
14
 
15
- @RestController
16
- @RequestMapping("/api/health")
17
- public class HealthController {
18
 
19
- @Autowired
20
- private DataSource dataSource;
21
 
22
- @GetMapping("/database")
23
- public ResponseEntity<Map<String, Object>> checkDatabaseConnection() {
24
- Map<String, Object> response = new HashMap<>();
25
 
26
- try (Connection connection = dataSource.getConnection()) {
27
- // Test the connection
28
- boolean isValid = connection.isValid(5); // 5 second timeout
29
 
30
- if (isValid) {
31
- response.put("status", "UP");
32
- response.put("database", "Connected");
33
- response.put("url", connection.getMetaData().getURL());
34
- response.put("driver", connection.getMetaData().getDriverName());
35
- response.put("version", connection.getMetaData().getDatabaseProductVersion());
36
- return ResponseEntity.ok(response);
37
- } else {
38
- response.put("status", "DOWN");
39
- response.put("database", "Connection invalid");
40
- return ResponseEntity.status(503).body(response);
41
- }
42
- } catch (SQLException e) {
43
- response.put("status", "DOWN");
44
- response.put("database", "Connection failed");
45
- response.put("error", e.getMessage());
46
- return ResponseEntity.status(503).body(response);
47
- }
48
- }
49
- }
 
1
+ // package com.cs102.attendance.controller;
2
 
3
+ // import org.springframework.beans.factory.annotation.Autowired;
4
+ // import org.springframework.http.ResponseEntity;
5
+ // import org.springframework.web.bind.annotation.GetMapping;
6
+ // import org.springframework.web.bind.annotation.RequestMapping;
7
+ // import org.springframework.web.bind.annotation.RestController;
8
 
9
+ // import javax.sql.DataSource;
10
+ // import java.sql.Connection;
11
+ // import java.sql.SQLException;
12
+ // import java.util.HashMap;
13
+ // import java.util.Map;
14
 
15
+ // @RestController
16
+ // @RequestMapping("/api/health")
17
+ // public class HealthController {
18
 
19
+ // @Autowired
20
+ // private DataSource dataSource;
21
 
22
+ // @GetMapping("/database")
23
+ // public ResponseEntity<Map<String, Object>> checkDatabaseConnection() {
24
+ // Map<String, Object> response = new HashMap<>();
25
 
26
+ // try (Connection connection = dataSource.getConnection()) {
27
+ // // Test the connection
28
+ // boolean isValid = connection.isValid(5); // 5 second timeout
29
 
30
+ // if (isValid) {
31
+ // response.put("status", "UP");
32
+ // response.put("database", "Connected");
33
+ // response.put("url", connection.getMetaData().getURL());
34
+ // response.put("driver", connection.getMetaData().getDriverName());
35
+ // response.put("version", connection.getMetaData().getDatabaseProductVersion());
36
+ // return ResponseEntity.ok(response);
37
+ // } else {
38
+ // response.put("status", "DOWN");
39
+ // response.put("database", "Connection invalid");
40
+ // return ResponseEntity.status(503).body(response);
41
+ // }
42
+ // } catch (SQLException e) {
43
+ // response.put("status", "DOWN");
44
+ // response.put("database", "Connection failed");
45
+ // response.put("error", e.getMessage());
46
+ // return ResponseEntity.status(503).body(response);
47
+ // }
48
+ // }
49
+ // }
src/main/java/com/cs102/attendance/controller/TestController.java CHANGED
@@ -1,75 +1,75 @@
1
- package com.cs102.attendance.controller;
2
 
3
- import com.cs102.attendance.entity.TestConnection;
4
- import com.cs102.attendance.repository.TestConnectionRepository;
5
- import org.springframework.beans.factory.annotation.Autowired;
6
- import org.springframework.http.ResponseEntity;
7
- import org.springframework.web.bind.annotation.*;
8
 
9
- import java.util.HashMap;
10
- import java.util.List;
11
- import java.util.Map;
12
 
13
- @RestController
14
- @RequestMapping("/api/test")
15
- public class TestController {
16
 
17
- @Autowired
18
- private TestConnectionRepository testConnectionRepository;
19
 
20
- @GetMapping("/database-operations")
21
- public ResponseEntity<Map<String, Object>> testDatabaseOperations() {
22
- Map<String, Object> response = new HashMap<>();
23
 
24
- try {
25
- // Test 1: Simple query
26
- Integer queryResult = testConnectionRepository.testQuery();
27
- response.put("simpleQuery", queryResult == 1 ? "PASS" : "FAIL");
28
 
29
- // Test 2: Insert operation
30
- TestConnection testEntity = new TestConnection("Connection test from Spring Boot");
31
- TestConnection saved = testConnectionRepository.save(testEntity);
32
- response.put("insertOperation", saved.getId() != null ? "PASS" : "FAIL");
33
 
34
- // Test 3: Read operation
35
- List<TestConnection> allRecords = testConnectionRepository.findAll();
36
- response.put("readOperation", !allRecords.isEmpty() ? "PASS" : "FAIL");
37
- response.put("recordCount", allRecords.size());
38
 
39
- // Test 4: Delete operation
40
- testConnectionRepository.deleteById(saved.getId());
41
- response.put("deleteOperation", "PASS");
42
 
43
- response.put("overallStatus", "SUCCESS");
44
- response.put("message", "All database operations completed successfully");
45
 
46
- return ResponseEntity.ok(response);
47
- } catch (Exception e) {
48
- response.put("overallStatus", "FAILED");
49
- response.put("error", e.getMessage());
50
- response.put("errorClass", e.getClass().getSimpleName());
51
- return ResponseEntity.status(500).body(response);
52
- }
53
- }
54
 
55
- @PostMapping("/insert-test-data")
56
- public ResponseEntity<TestConnection> insertTestData(@RequestParam(defaultValue = "Test message") String message) {
57
- try {
58
- TestConnection testEntity = new TestConnection(message);
59
- TestConnection saved = testConnectionRepository.save(testEntity);
60
- return ResponseEntity.ok(saved);
61
- } catch (Exception e) {
62
- return ResponseEntity.status(500).build();
63
- }
64
- }
65
 
66
- @GetMapping("/all-test-data")
67
- public ResponseEntity<List<TestConnection>> getAllTestData() {
68
- try {
69
- List<TestConnection> allRecords = testConnectionRepository.findAll();
70
- return ResponseEntity.ok(allRecords);
71
- } catch (Exception e) {
72
- return ResponseEntity.status(500).build();
73
- }
74
- }
75
- }
 
1
+ // package com.cs102.attendance.controller;
2
 
3
+ // import com.cs102.attendance.entity.TestConnection;
4
+ // import com.cs102.attendance.repository.TestConnectionRepository;
5
+ // import org.springframework.beans.factory.annotation.Autowired;
6
+ // import org.springframework.http.ResponseEntity;
7
+ // import org.springframework.web.bind.annotation.*;
8
 
9
+ // import java.util.HashMap;
10
+ // import java.util.List;
11
+ // import java.util.Map;
12
 
13
+ // @RestController
14
+ // @RequestMapping("/api/test")
15
+ // public class TestController {
16
 
17
+ // @Autowired
18
+ // private TestConnectionRepository testConnectionRepository;
19
 
20
+ // @GetMapping("/database-operations")
21
+ // public ResponseEntity<Map<String, Object>> testDatabaseOperations() {
22
+ // Map<String, Object> response = new HashMap<>();
23
 
24
+ // try {
25
+ // // Test 1: Simple query
26
+ // Integer queryResult = testConnectionRepository.testQuery();
27
+ // response.put("simpleQuery", queryResult == 1 ? "PASS" : "FAIL");
28
 
29
+ // // Test 2: Insert operation
30
+ // TestConnection testEntity = new TestConnection("Connection test from Spring Boot");
31
+ // TestConnection saved = testConnectionRepository.save(testEntity);
32
+ // response.put("insertOperation", saved.getId() != null ? "PASS" : "FAIL");
33
 
34
+ // // Test 3: Read operation
35
+ // List<TestConnection> allRecords = testConnectionRepository.findAll();
36
+ // response.put("readOperation", !allRecords.isEmpty() ? "PASS" : "FAIL");
37
+ // response.put("recordCount", allRecords.size());
38
 
39
+ // // Test 4: Delete operation
40
+ // testConnectionRepository.deleteById(saved.getId());
41
+ // response.put("deleteOperation", "PASS");
42
 
43
+ // response.put("overallStatus", "SUCCESS");
44
+ // response.put("message", "All database operations completed successfully");
45
 
46
+ // return ResponseEntity.ok(response);
47
+ // } catch (Exception e) {
48
+ // response.put("overallStatus", "FAILED");
49
+ // response.put("error", e.getMessage());
50
+ // response.put("errorClass", e.getClass().getSimpleName());
51
+ // return ResponseEntity.status(500).body(response);
52
+ // }
53
+ // }
54
 
55
+ // @PostMapping("/insert-test-data")
56
+ // public ResponseEntity<TestConnection> insertTestData(@RequestParam(defaultValue = "Test message") String message) {
57
+ // try {
58
+ // TestConnection testEntity = new TestConnection(message);
59
+ // TestConnection saved = testConnectionRepository.save(testEntity);
60
+ // return ResponseEntity.ok(saved);
61
+ // } catch (Exception e) {
62
+ // return ResponseEntity.status(500).build();
63
+ // }
64
+ // }
65
 
66
+ // @GetMapping("/all-test-data")
67
+ // public ResponseEntity<List<TestConnection>> getAllTestData() {
68
+ // try {
69
+ // List<TestConnection> allRecords = testConnectionRepository.findAll();
70
+ // return ResponseEntity.ok(allRecords);
71
+ // } catch (Exception e) {
72
+ // return ResponseEntity.status(500).build();
73
+ // }
74
+ // }
75
+ // }
src/main/java/com/cs102/attendance/entity/TestConnection.java CHANGED
@@ -1,53 +1,53 @@
1
- package com.cs102.attendance.entity;
2
 
3
- import jakarta.persistence.*;
4
- import java.time.LocalDateTime;
5
 
6
- @Entity
7
- @Table(name = "test_connections")
8
- public class TestConnection {
9
-
10
- @Id
11
- @GeneratedValue(strategy = GenerationType.IDENTITY)
12
- private Long id;
13
-
14
- @Column(name = "test_message")
15
- private String testMessage;
16
-
17
- @Column(name = "created_at")
18
- private LocalDateTime createdAt;
19
-
20
- public TestConnection() {
21
- this.createdAt = LocalDateTime.now();
22
- }
23
-
24
- public TestConnection(String testMessage) {
25
- this.testMessage = testMessage;
26
- this.createdAt = LocalDateTime.now();
27
- }
28
-
29
- // Getters and setters
30
- public Long getId() {
31
- return id;
32
- }
33
-
34
- public void setId(Long id) {
35
- this.id = id;
36
- }
37
-
38
- public String getTestMessage() {
39
- return testMessage;
40
- }
41
-
42
- public void setTestMessage(String testMessage) {
43
- this.testMessage = testMessage;
44
- }
45
-
46
- public LocalDateTime getCreatedAt() {
47
- return createdAt;
48
- }
49
-
50
- public void setCreatedAt(LocalDateTime createdAt) {
51
- this.createdAt = createdAt;
52
- }
53
- }
 
1
+ // package com.cs102.attendance.entity;
2
 
3
+ // import jakarta.persistence.*;
4
+ // import java.time.LocalDateTime;
5
 
6
+ // @Entity
7
+ // @Table(name = "test_connections")
8
+ // public class TestConnection {
9
+
10
+ // @Id
11
+ // @GeneratedValue(strategy = GenerationType.IDENTITY)
12
+ // private Long id;
13
+
14
+ // @Column(name = "test_message")
15
+ // private String testMessage;
16
+
17
+ // @Column(name = "created_at")
18
+ // private LocalDateTime createdAt;
19
+
20
+ // public TestConnection() {
21
+ // this.createdAt = LocalDateTime.now();
22
+ // }
23
+
24
+ // public TestConnection(String testMessage) {
25
+ // this.testMessage = testMessage;
26
+ // this.createdAt = LocalDateTime.now();
27
+ // }
28
+
29
+ // // Getters and setters
30
+ // public Long getId() {
31
+ // return id;
32
+ // }
33
+
34
+ // public void setId(Long id) {
35
+ // this.id = id;
36
+ // }
37
+
38
+ // public String getTestMessage() {
39
+ // return testMessage;
40
+ // }
41
+
42
+ // public void setTestMessage(String testMessage) {
43
+ // this.testMessage = testMessage;
44
+ // }
45
+
46
+ // public LocalDateTime getCreatedAt() {
47
+ // return createdAt;
48
+ // }
49
+
50
+ // public void setCreatedAt(LocalDateTime createdAt) {
51
+ // this.createdAt = createdAt;
52
+ // }
53
+ // }
src/main/java/com/cs102/attendance/repository/TestConnectionRepository.java CHANGED
@@ -1,13 +1,13 @@
1
- package com.cs102.attendance.repository;
2
 
3
- import com.cs102.attendance.entity.TestConnection;
4
- import org.springframework.data.jpa.repository.JpaRepository;
5
- import org.springframework.data.jpa.repository.Query;
6
- import org.springframework.stereotype.Repository;
7
 
8
- @Repository
9
- public interface TestConnectionRepository extends JpaRepository<TestConnection, Long> {
10
 
11
- @Query(value = "SELECT 1", nativeQuery = true)
12
- Integer testQuery();
13
- }
 
1
+ // package com.cs102.attendance.repository;
2
 
3
+ // import com.cs102.attendance.entity.TestConnection;
4
+ // import org.springframework.data.jpa.repository.JpaRepository;
5
+ // import org.springframework.data.jpa.repository.Query;
6
+ // import org.springframework.stereotype.Repository;
7
 
8
+ // @Repository
9
+ // public interface TestConnectionRepository extends JpaRepository<TestConnection, Long> {
10
 
11
+ // @Query(value = "SELECT 1", nativeQuery = true)
12
+ // Integer testQuery();
13
+ // }
src/main/java/com/cs102/attendance/service/FastApiCallerService.java CHANGED
@@ -1,42 +1,50 @@
1
- // FastApiCallerService.java
2
  package com.cs102.attendance.service;
3
 
4
- import java.net.URI;
5
- import java.net.http.HttpClient;
6
- import java.net.http.HttpRequest;
7
- import java.net.http.HttpResponse;
8
-
 
9
  import org.springframework.stereotype.Service;
10
-
11
- import com.fasterxml.jackson.databind.JsonNode;
12
- import com.fasterxml.jackson.databind.ObjectMapper;
13
 
14
  @Service
15
  public class FastApiCallerService {
16
 
 
17
  private static final String FASTAPI_URL = "https://kevansoon-java-facerecognition-endpoint.hf.space/face-recognition";
18
 
19
- private final HttpClient httpClient;
20
- private final ObjectMapper objectMapper;
21
-
22
  public FastApiCallerService() {
23
- this.httpClient = HttpClient.newHttpClient();
24
- this.objectMapper = new ObjectMapper();
25
  }
26
 
27
- public String callFaceRecognition() throws Exception {
28
- HttpRequest request = HttpRequest.newBuilder()
29
- .GET()
30
- .uri(URI.create(FASTAPI_URL))
31
- .build();
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
- HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
34
 
35
- if (response.statusCode() == 200) {
36
- JsonNode jsonNode = objectMapper.readTree(response.body());
37
- return jsonNode.path("result").asText();
38
  } else {
39
- throw new RuntimeException("Failed to call FastAPI: HTTP " + response.statusCode());
40
  }
41
  }
42
  }
 
 
1
  package com.cs102.attendance.service;
2
 
3
+ import org.springframework.core.io.ByteArrayResource;
4
+ import org.springframework.http.HttpEntity;
5
+ import org.springframework.http.HttpHeaders;
6
+ import org.springframework.http.MediaType;
7
+ import org.springframework.http.ResponseEntity;
8
+ import org.springframework.http.client.SimpleClientHttpRequestFactory;
9
  import org.springframework.stereotype.Service;
10
+ import org.springframework.util.LinkedMultiValueMap;
11
+ import org.springframework.web.client.RestTemplate;
12
+ import org.springframework.web.multipart.MultipartFile;
13
 
14
  @Service
15
  public class FastApiCallerService {
16
 
17
+ private final RestTemplate restTemplate;
18
  private static final String FASTAPI_URL = "https://kevansoon-java-facerecognition-endpoint.hf.space/face-recognition";
19
 
 
 
 
20
  public FastApiCallerService() {
21
+ this.restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory());
 
22
  }
23
 
24
+ public String callFaceRecognitionWithImage(MultipartFile image) throws Exception {
25
+ // Wrap MultipartFile bytes with filename
26
+ ByteArrayResource imageAsResource = new ByteArrayResource(image.getBytes()) {
27
+ @Override
28
+ public String getFilename() {
29
+ return image.getOriginalFilename();
30
+ }
31
+ };
32
+
33
+ // Prepare multipart form data
34
+ LinkedMultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
35
+ body.add("image", imageAsResource);
36
+
37
+ HttpHeaders headers = new HttpHeaders();
38
+ headers.setContentType(MediaType.MULTIPART_FORM_DATA);
39
+
40
+ HttpEntity<LinkedMultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
41
 
42
+ ResponseEntity<String> response = restTemplate.postForEntity(FASTAPI_URL, requestEntity, String.class);
43
 
44
+ if (response.getStatusCode().is2xxSuccessful()) {
45
+ return response.getBody(); // Or parse JSON if needed
 
46
  } else {
47
+ throw new RuntimeException("Failed to call FastAPI: HTTP " + response.getStatusCodeValue());
48
  }
49
  }
50
  }
src/test/java/com/cs102/attendance/Cs102AttendanceProjectApplicationTests.java CHANGED
@@ -1,50 +1,50 @@
1
- package com.cs102.attendance;
2
 
3
- import com.cs102.attendance.repository.TestConnectionRepository;
4
- import org.junit.jupiter.api.Test;
5
- import org.springframework.beans.factory.annotation.Autowired;
6
- import org.springframework.boot.test.context.SpringBootTest;
7
 
8
- import javax.sql.DataSource;
9
- import java.sql.Connection;
10
- import java.sql.SQLException;
11
 
12
- import static org.junit.jupiter.api.Assertions.*;
13
 
14
- @SpringBootTest
15
- class Cs102AttendanceProjectApplicationTests {
16
 
17
- @Autowired
18
- private DataSource dataSource;
19
 
20
- @Autowired
21
- private TestConnectionRepository testConnectionRepository;
22
 
23
- @Test
24
- void contextLoads() {
25
- }
26
 
27
- @Test
28
- void testDatabaseConnection() throws SQLException {
29
- // Test that we can get a connection from the DataSource
30
- try (Connection connection = dataSource.getConnection()) {
31
- assertNotNull(connection, "Database connection should not be null");
32
- assertTrue(connection.isValid(5), "Database connection should be valid");
33
 
34
- // Print connection details for verification
35
- System.out.println("Database URL: " + connection.getMetaData().getURL());
36
- System.out.println("Database Driver: " + connection.getMetaData().getDriverName());
37
- System.out.println("Database Version: " + connection.getMetaData().getDatabaseProductVersion());
38
- }
39
- }
40
-
41
- @Test
42
- void testRepositoryConnection() {
43
- // Test that the repository can execute queries
44
- assertDoesNotThrow(() -> {
45
- Integer result = testConnectionRepository.testQuery();
46
- assertEquals(1, result, "Test query should return 1");
47
- }, "Repository test query should not throw an exception");
48
- }
49
-
50
- }
 
1
+ // package com.cs102.attendance;
2
 
3
+ // import com.cs102.attendance.repository.TestConnectionRepository;
4
+ // import org.junit.jupiter.api.Test;
5
+ // import org.springframework.beans.factory.annotation.Autowired;
6
+ // import org.springframework.boot.test.context.SpringBootTest;
7
 
8
+ // import javax.sql.DataSource;
9
+ // import java.sql.Connection;
10
+ // import java.sql.SQLException;
11
 
12
+ // import static org.junit.jupiter.api.Assertions.*;
13
 
14
+ // @SpringBootTest
15
+ // class Cs102AttendanceProjectApplicationTests {
16
 
17
+ // @Autowired
18
+ // private DataSource dataSource;
19
 
20
+ // @Autowired
21
+ // private TestConnectionRepository testConnectionRepository;
22
 
23
+ // @Test
24
+ // void contextLoads() {
25
+ // }
26
 
27
+ // @Test
28
+ // void testDatabaseConnection() throws SQLException {
29
+ // // Test that we can get a connection from the DataSource
30
+ // try (Connection connection = dataSource.getConnection()) {
31
+ // assertNotNull(connection, "Database connection should not be null");
32
+ // assertTrue(connection.isValid(5), "Database connection should be valid");
33
 
34
+ // // Print connection details for verification
35
+ // System.out.println("Database URL: " + connection.getMetaData().getURL());
36
+ // System.out.println("Database Driver: " + connection.getMetaData().getDriverName());
37
+ // System.out.println("Database Version: " + connection.getMetaData().getDatabaseProductVersion());
38
+ // }
39
+ // }
40
+
41
+ // @Test
42
+ // void testRepositoryConnection() {
43
+ // // Test that the repository can execute queries
44
+ // assertDoesNotThrow(() -> {
45
+ // Integer result = testConnectionRepository.testQuery();
46
+ // assertEquals(1, result, "Test query should return 1");
47
+ // }, "Repository test query should not throw an exception");
48
+ // }
49
+
50
+ // }
src/test/java/com/cs102/attendance/controller/TestControllerTest.java CHANGED
@@ -1,69 +1,69 @@
1
- package com.cs102.attendance.controller;
2
 
3
- import com.cs102.attendance.entity.TestConnection;
4
- import com.cs102.attendance.repository.TestConnectionRepository;
5
- import org.junit.jupiter.api.Test;
6
- import org.springframework.beans.factory.annotation.Autowired;
7
- import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
8
- import org.springframework.test.context.bean.override.mockito.MockitoBean;
9
- import org.springframework.http.MediaType;
10
- import org.springframework.test.web.servlet.MockMvc;
11
 
12
- import static org.mockito.ArgumentMatchers.any;
13
- import static org.mockito.Mockito.when;
14
- import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
15
- import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
16
 
17
- @WebMvcTest(TestController.class)
18
- public class TestControllerTest {
19
 
20
- @Autowired
21
- private MockMvc mockMvc;
22
 
23
- @MockitoBean
24
- private TestConnectionRepository testConnectionRepository;
25
 
26
- @Test
27
- public void testInsertTestDataWithDefaultMessage() throws Exception {
28
- // Given
29
- TestConnection mockSavedEntity = new TestConnection("Test message");
30
- mockSavedEntity.setId(1L);
31
- when(testConnectionRepository.save(any(TestConnection.class))).thenReturn(mockSavedEntity);
32
 
33
- // When & Then
34
- mockMvc.perform(post("/api/test/insert-test-data")
35
- .contentType(MediaType.APPLICATION_JSON))
36
- .andExpect(status().isOk())
37
- .andExpect(jsonPath("$.id").value(1L))
38
- .andExpect(jsonPath("$.message").value("Test message"));
39
- }
40
 
41
- @Test
42
- public void testInsertTestDataWithCustomMessage() throws Exception {
43
- // Given
44
- String customMessage = "Custom test message";
45
- TestConnection mockSavedEntity = new TestConnection(customMessage);
46
- mockSavedEntity.setId(2L);
47
- when(testConnectionRepository.save(any(TestConnection.class))).thenReturn(mockSavedEntity);
48
 
49
- // When & Then
50
- mockMvc.perform(post("/api/test/insert-test-data")
51
- .param("message", customMessage)
52
- .contentType(MediaType.APPLICATION_JSON))
53
- .andExpect(status().isOk())
54
- .andExpect(jsonPath("$.id").value(2L))
55
- .andExpect(jsonPath("$.message").value(customMessage));
56
- }
57
 
58
- @Test
59
- public void testInsertTestDataWithException() throws Exception {
60
- // Given
61
- when(testConnectionRepository.save(any(TestConnection.class)))
62
- .thenThrow(new RuntimeException("Database error"));
63
 
64
- // When & Then
65
- mockMvc.perform(post("/api/test/insert-test-data")
66
- .contentType(MediaType.APPLICATION_JSON))
67
- .andExpect(status().isInternalServerError());
68
- }
69
- }
 
1
+ // package com.cs102.attendance.controller;
2
 
3
+ // import com.cs102.attendance.entity.TestConnection;
4
+ // import com.cs102.attendance.repository.TestConnectionRepository;
5
+ // import org.junit.jupiter.api.Test;
6
+ // import org.springframework.beans.factory.annotation.Autowired;
7
+ // import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
8
+ // import org.springframework.test.context.bean.override.mockito.MockitoBean;
9
+ // import org.springframework.http.MediaType;
10
+ // import org.springframework.test.web.servlet.MockMvc;
11
 
12
+ // import static org.mockito.ArgumentMatchers.any;
13
+ // import static org.mockito.Mockito.when;
14
+ // import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
15
+ // import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
16
 
17
+ // @WebMvcTest(TestController.class)
18
+ // public class TestControllerTest {
19
 
20
+ // @Autowired
21
+ // private MockMvc mockMvc;
22
 
23
+ // @MockitoBean
24
+ // private TestConnectionRepository testConnectionRepository;
25
 
26
+ // @Test
27
+ // public void testInsertTestDataWithDefaultMessage() throws Exception {
28
+ // // Given
29
+ // TestConnection mockSavedEntity = new TestConnection("Test message");
30
+ // mockSavedEntity.setId(1L);
31
+ // when(testConnectionRepository.save(any(TestConnection.class))).thenReturn(mockSavedEntity);
32
 
33
+ // // When & Then
34
+ // mockMvc.perform(post("/api/test/insert-test-data")
35
+ // .contentType(MediaType.APPLICATION_JSON))
36
+ // .andExpect(status().isOk())
37
+ // .andExpect(jsonPath("$.id").value(1L))
38
+ // .andExpect(jsonPath("$.message").value("Test message"));
39
+ // }
40
 
41
+ // @Test
42
+ // public void testInsertTestDataWithCustomMessage() throws Exception {
43
+ // // Given
44
+ // String customMessage = "Custom test message";
45
+ // TestConnection mockSavedEntity = new TestConnection(customMessage);
46
+ // mockSavedEntity.setId(2L);
47
+ // when(testConnectionRepository.save(any(TestConnection.class))).thenReturn(mockSavedEntity);
48
 
49
+ // // When & Then
50
+ // mockMvc.perform(post("/api/test/insert-test-data")
51
+ // .param("message", customMessage)
52
+ // .contentType(MediaType.APPLICATION_JSON))
53
+ // .andExpect(status().isOk())
54
+ // .andExpect(jsonPath("$.id").value(2L))
55
+ // .andExpect(jsonPath("$.message").value(customMessage));
56
+ // }
57
 
58
+ // @Test
59
+ // public void testInsertTestDataWithException() throws Exception {
60
+ // // Given
61
+ // when(testConnectionRepository.save(any(TestConnection.class)))
62
+ // .thenThrow(new RuntimeException("Database error"));
63
 
64
+ // // When & Then
65
+ // mockMvc.perform(post("/api/test/insert-test-data")
66
+ // .contentType(MediaType.APPLICATION_JSON))
67
+ // .andExpect(status().isInternalServerError());
68
+ // }
69
+ // }
video-object-detection/main.js CHANGED
@@ -61,6 +61,37 @@ const COLOURS = [
61
  ];
62
 
63
  // Function to send canvas image to Gradio API
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  async function sendCanvasImageToAPI(canvas) {
65
  return new Promise((resolve, reject) => {
66
  canvas.toBlob(async (blob) => {
@@ -69,21 +100,23 @@ async function sendCanvasImageToAPI(canvas) {
69
  return;
70
  }
71
 
72
- const file1 = new File([blob], "detected.png", { type: "image/png" });
73
 
74
  try {
75
- // Fetch image from URL and convert to Blob
76
- const response = await fetch("https://qvnhhditkzzeudppuezf.supabase.co/storage/v1/object/public/post-images/post-images/1752289670997-kevan.jpg");
77
- const frame2Blob = await response.blob();
78
- const file2 = new File([frame2Blob], "frame2.jpg", { type: frame2Blob.type });
79
-
80
- const client = await Client.connect("MiniAiLive/FaceRecognition-LivenessDetection-Demo");
81
 
82
- // Send canvas image as frame1, URL image as frame2
83
- const result = await client.predict("/face_compare", {
84
- frame1: file1,
85
- frame2: file2,
86
  });
 
 
 
 
 
 
 
87
  resolve(result);
88
  } catch (err) {
89
  reject(err);
@@ -92,6 +125,7 @@ async function sendCanvasImageToAPI(canvas) {
92
  });
93
  }
94
 
 
95
  // Variables to store current bounding box and label elements
96
  let currentBoxElement = null;
97
  let currentLabelElement = null;
@@ -135,15 +169,19 @@ function renderBox([xmin, ymin, xmax, ymax, score, id], [w, h]) {
135
  if (!hasSent) {
136
  hasSent = true;
137
  sendCanvasImageToAPI(canvas)
138
- .then((result) => {
139
- console.log("API result:", result);
140
-
141
- const str = result.data[0]; // Access first element in array
142
- const startIndex = str.indexOf("Similarity");
143
- const slicedStr = startIndex !== -1 ? str.slice(startIndex) : "";
144
- const decimalMatch = slicedStr.match(/<td>(0?\.\d+)<\/td>/);
145
- const decimalNumber = decimalMatch ? parseFloat(decimalMatch[1]) : null;
146
- console.log("Similarity decimal:", decimalNumber);
 
 
 
 
147
 
148
  if (decimalNumber !== null && decimalNumber > 0.80) {
149
  // --- MODIFICATION START ---
 
61
  ];
62
 
63
  // Function to send canvas image to Gradio API
64
+ // async function sendCanvasImageToAPI(canvas) {
65
+ // return new Promise((resolve, reject) => {
66
+ // canvas.toBlob(async (blob) => {
67
+ // if (!blob) {
68
+ // reject("Failed to get Blob from canvas");
69
+ // return;
70
+ // }
71
+
72
+ // const file1 = new File([blob], "detected.png", { type: "image/png" });
73
+
74
+ // try {
75
+ // // Fetch image from URL and convert to Blob
76
+ // const response = await fetch("https://qvnhhditkzzeudppuezf.supabase.co/storage/v1/object/public/post-images/post-images/1752289670997-kevan.jpg");
77
+ // const frame2Blob = await response.blob();
78
+ // const file2 = new File([frame2Blob], "frame2.jpg", { type: frame2Blob.type });
79
+
80
+ // const client = await Client.connect("MiniAiLive/FaceRecognition-LivenessDetection-Demo");
81
+
82
+ // // Send canvas image as frame1, URL image as frame2
83
+ // const result = await client.predict("/face_compare", {
84
+ // frame1: file1,
85
+ // frame2: file2,
86
+ // });
87
+ // resolve(result);
88
+ // } catch (err) {
89
+ // reject(err);
90
+ // }
91
+ // }, "image/png");
92
+ // });
93
+ // }
94
+
95
  async function sendCanvasImageToAPI(canvas) {
96
  return new Promise((resolve, reject) => {
97
  canvas.toBlob(async (blob) => {
 
100
  return;
101
  }
102
 
103
+ const file = new File([blob], "detected.png", { type: "image/png" });
104
 
105
  try {
106
+ const formData = new FormData();
107
+ formData.append("image", file);
 
 
 
 
108
 
109
+ const response = await fetch("http://localhost:8080/call-face-recognition", {
110
+ method: "POST",
111
+ body: formData,
 
112
  });
113
+
114
+ if (!response.ok) {
115
+ reject("Failed to send image: " + response.statusText);
116
+ return;
117
+ }
118
+
119
+ const result = await response.text(); // or JSON if backend returns JSON
120
  resolve(result);
121
  } catch (err) {
122
  reject(err);
 
125
  });
126
  }
127
 
128
+
129
  // Variables to store current bounding box and label elements
130
  let currentBoxElement = null;
131
  let currentLabelElement = null;
 
169
  if (!hasSent) {
170
  hasSent = true;
171
  sendCanvasImageToAPI(canvas)
172
+ .then((response) => {
173
+
174
+ const responseObj = JSON.parse(response);
175
+ const confidenceStr = responseObj.result; // "0.982708"
176
+
177
+ // Extract decimal part only:
178
+ // const decimalPart = confidenceStr.slice(confidenceStr.indexOf('.') + 1);
179
+ // console.log(decimalPart); // e.g., "982708"
180
+
181
+ // Convert to float for comparison
182
+ const decimalNumber = parseFloat(confidenceStr);
183
+ console.log(decimalNumber);
184
+
185
 
186
  if (decimalNumber !== null && decimalNumber > 0.80) {
187
  // --- MODIFICATION START ---