From fa33eb0863583635ab95affff349a30878dfbea5 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:00:39 +0400 Subject: [PATCH 01/29] Creating first model class --- .../models/MeasurementsHistory.java | 4 ++++ tatus | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java create mode 100644 tatus diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java new file mode 100644 index 0000000..b4a7f32 --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java @@ -0,0 +1,4 @@ +package com.oraclequantapi.oraclequantapi.models; + +public class MeasurementsHistory { +} diff --git a/tatus b/tatus new file mode 100644 index 0000000..851de95 --- /dev/null +++ b/tatus @@ -0,0 +1,17 @@ +commit 56b42d8cbe52fbf5e5c09c6b3fe33f4cff5a6a4b (HEAD -> ibrahim-submission-branch, origin/main, origin/HEAD, main) +Author: Syed Atyab Hussain <119934383+CodelineAtyab@users.noreply.github.com> +Date: Wed May 20 12:18:04 2026 +0400 + + Update README.md + +commit 9dd10622247ad669593fea7420d47916d339b153 +Author: Syed Atyab Hussain +Date: Wed May 20 12:11:45 2026 +0400 + + Initialized and empty SpringBoot Project + +commit daa75b6e7f160ad42127809aa6371a104373343b +Author: Syed Atyab Hussain +Date: Wed May 20 12:08:50 2026 +0400 + + first commit From cb06dfeda4dca4ce9999725055925efa8870fb31 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:02:29 +0400 Subject: [PATCH 02/29] Creating second model class --- .../oraclequantapi/models/MeasurementsSequence.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java new file mode 100644 index 0000000..cf63339 --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java @@ -0,0 +1,4 @@ +package com.oraclequantapi.oraclequantapi.models; + +public class MeasurementsSequence { +} From 2e03e5a396ef5ce52ca0f57e25909da7795d11ec Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:06:27 +0400 Subject: [PATCH 03/29] Adding value to hold the input --- .../oraclequantapi/models/MeasurementsSequence.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java index cf63339..e4fb81b 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java @@ -1,4 +1,13 @@ package com.oraclequantapi.oraclequantapi.models; public class MeasurementsSequence { + + public String value; + + public MeasurementsSequence(String value){ + setValue(value); + } + + private void setValue(String value) { + } } From febb8393893641c19866423fe0ab18960090b942 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:11:09 +0400 Subject: [PATCH 04/29] Adding condition statement to normalize the inputs --- .../oraclequantapi/models/MeasurementsSequence.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java index e4fb81b..9cc6f2f 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java @@ -1,5 +1,7 @@ package com.oraclequantapi.oraclequantapi.models; +import static sun.security.krb5.internal.ktab.KeyTab.normalize; + public class MeasurementsSequence { public String value; @@ -8,6 +10,13 @@ public MeasurementsSequence(String value){ setValue(value); } + // capital letters converted into lowercases + // Anything than letters and underscore will be converted into underscore private void setValue(String value) { + if (value == null) { + this.value = null; + } else { + this.value = normalize(value); + } } } From 4a6c57e234e258521a0a763824df9380957b5372 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:23:27 +0400 Subject: [PATCH 05/29] Updating condition statement to normalize the inputs --- .../models/MeasurementsSequence.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java index 9cc6f2f..8b50fd8 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java @@ -1,6 +1,7 @@ package com.oraclequantapi.oraclequantapi.models; -import static sun.security.krb5.internal.ktab.KeyTab.normalize; + +import java.util.Locale; public class MeasurementsSequence { @@ -19,4 +20,20 @@ private void setValue(String value) { this.value = normalize(value); } } + + private String normalize (String value){ + String lowerValue = value.toLowerCase(Locale.ROOT); + StringBuilder normalizedValue = new StringBuilder(); + + for (int index = 0; index < lowerValue.length(); index++) { + char current = lowerValue.charAt(index); + + if ((current >= 'a' && current <= 'z') || current == '_') { + normalizedValue.append(current); + }else { + normalizedValue.append('_'); + } + } + return normalizedValue.toString(); + } } From b0859cf0d8231002397e3a5e84f9a606876171dc Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:45:00 +0400 Subject: [PATCH 06/29] Updating Maven pom.xml --- pom.xml | 6 ++++++ .../oraclequantapi/models/MeasurementsHistory.java | 2 ++ 2 files changed, 8 insertions(+) diff --git a/pom.xml b/pom.xml index 20909d2..767304b 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,12 @@ spring-boot-starter-web + + com.oracle.database.jdbc + ojdbc11 + runtime + + org.springframework.boot spring-boot-starter-test diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java index b4a7f32..a564661 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java @@ -1,4 +1,6 @@ package com.oraclequantapi.oraclequantapi.models; +@Entity public class MeasurementsHistory { + } From 0cb427147baf09661206962362cce0bdc9dd0b3b Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:47:50 +0400 Subject: [PATCH 07/29] Updating Maven pom.xml --- pom.xml | 5 +++++ .../oraclequantapi/models/MeasurementsHistory.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 767304b..3e0a3be 100644 --- a/pom.xml +++ b/pom.xml @@ -35,6 +35,11 @@ spring-boot-starter-web + + org.springframework.boot + spring-boot-starter-data-jpa + + com.oracle.database.jdbc ojdbc11 diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java index a564661..557a0f5 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java @@ -1,5 +1,7 @@ package com.oraclequantapi.oraclequantapi.models; +import jakarta.persistence.Entity; + @Entity public class MeasurementsHistory { From 4af717b57327759777e11bf8b00f4dc7eaac1e57 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:50:24 +0400 Subject: [PATCH 08/29] Initializing the table --- .../oraclequantapi/models/MeasurementsHistory.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java index 557a0f5..e321481 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java @@ -1,8 +1,17 @@ package com.oraclequantapi.oraclequantapi.models; +import jakarta.persistence.Column; import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; @Entity +@Table(name = "MEASUREMENT_TABLE") public class MeasurementsHistory { + @Id + @Column(name = "ID", length = 36) + public String id; + + } From bbd47c830c54442e8a16797a31a46522b77e8d5f Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:53:47 +0400 Subject: [PATCH 09/29] Completing the table --- .../models/MeasurementsHistory.java | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java index e321481..ec4939f 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java @@ -1,9 +1,9 @@ package com.oraclequantapi.oraclequantapi.models; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.persistence.*; + +import java.time.LocalDateTime; @Entity @Table(name = "MEASUREMENT_TABLE") @@ -13,5 +13,24 @@ public class MeasurementsHistory { @Column(name = "ID", length = 36) public String id; + // Time when the API received the conversion request. + @Column(name = "REQUEST_TIMESTAMP") + public LocalDateTime timestamp; + + // Client IP address. JsonProperty makes the JSON name match the task wording. + @JsonProperty("source_ip_address") + @Column(name = "SOURCE_IP_ADDRESS") + public String sourceIpAddress; + + + // Normalized input string after converting capital letters to lowercase. + @Lob + @Column(name = "MEASUREMENT_INPUT") + public String input; + + // Output is stored as text, for example "[2,6]". + @Lob + @Column(name = "MEASUREMENT_OUTPUT") + public String output; } From ce319446cdcf496a636b67b42a97c60b19480140 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:54:23 +0400 Subject: [PATCH 10/29] Completing the table --- .../oraclequantapi/models/MeasurementsHistory.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java index ec4939f..b4cee40 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java @@ -9,6 +9,7 @@ @Table(name = "MEASUREMENT_TABLE") public class MeasurementsHistory { + // UUID string @Id @Column(name = "ID", length = 36) public String id; From 214ddc08d9005954b168d9376bc5bec5a5898832 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 11:57:09 +0400 Subject: [PATCH 11/29] Creating Measurements repository --- .../repositories/MeasurementRepository.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementRepository.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementRepository.java b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementRepository.java new file mode 100644 index 0000000..7b01295 --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementRepository.java @@ -0,0 +1,10 @@ +package com.oraclequantapi.oraclequantapi.repositories; + +import om.oraclequant.pkc_api.models.MeasurementHistory; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface MeasurementHistoryRepository extends JpaRepository { + // JpaRepository already provides: findAll, findById, save, deleteById, deleteAll. +} From 1b06e8372031495a0a2cb507f40f6b8d9756b2a6 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:09:41 +0400 Subject: [PATCH 12/29] Creating services classes --- .../oraclequantapi/services/HistoryService.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java new file mode 100644 index 0000000..f9b0d3b --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java @@ -0,0 +1,13 @@ +package com.oraclequantapi.oraclequantapi.services; + +import com.oraclequantapi.oraclequantapi.repositories.MeasurementHistoryRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Service +public class HistoryService { + + @Autowired + private MeasurementHistoryRepository measurementHistoryRepository; + +} From d1ed756fc548636a4061243f904bbab758889e3c Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:10:58 +0400 Subject: [PATCH 13/29] Adding Oracle db field --- .../services/HistoryService.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java index f9b0d3b..444ad3c 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java @@ -4,10 +4,28 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.time.LocalDateTime; +import java.util.List; +import java.util.UUID; + @Service public class HistoryService { @Autowired private MeasurementHistoryRepository measurementHistoryRepository; + // Save one conversion request into Oracle DB + public MeasurementHistory saveCurrentMeasurement( + String sourceIpAddress, + MeasurementSequence sequence, + List output + ) { + MeasurementHistory history = new MeasurementHistory(); + history.id = UUID.randomUUID().toString(); + history.timestamp = LocalDateTime.now(); + history.sourceIpAddress = sourceIpAddress; + history.input = sequence.getValueAsString(); + history.output = formatOutput(output); + return measurementHistoryRepository.save(history); + } } From b351ec136b5b8dfc14b7882a4386a88c0dec25a5 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:12:24 +0400 Subject: [PATCH 14/29] Updatring service class --- .../services/HistoryService.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java index 444ad3c..af7647a 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java @@ -7,6 +7,7 @@ import java.time.LocalDateTime; import java.util.List; import java.util.UUID; +import java.util.stream.Collectors; @Service public class HistoryService { @@ -28,4 +29,40 @@ public MeasurementHistory saveCurrentMeasurement( history.output = formatOutput(output); return measurementHistoryRepository.save(history); } + public MeasurementHistory getHistoryById(String id) { + return measurementHistoryRepository.findById(id).orElse(null); + } + // PUT uses this method. Only non-null fields are changed. + public MeasurementHistory updateHistory(String id, MeasurementHistory givenHistory) { + MeasurementHistory existingHistory = getHistoryById(id); + + if (existingHistory == null) { + return null; + } + + if (givenHistory.sourceIpAddress != null) { + existingHistory.sourceIpAddress = givenHistory.sourceIpAddress; + } + + if (givenHistory.input != null) { + existingHistory.input = givenHistory.input; + } + + if (givenHistory.output != null) { + existingHistory.output = givenHistory.output; + } + + return measurementHistoryRepository.save(existingHistory); + } + + public void clearHistory() { + measurementHistoryRepository.deleteAll(); + } + + // Converts List into text before storing it in Oracle DB. + private String formatOutput(List output) { + return output.stream() + .map(String::valueOf) + .collect(Collectors.joining(",", "[", "]")); + } } From 2b9683b4eda264a020a6bcf3a4eaba10de13332a Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:16:01 +0400 Subject: [PATCH 15/29] Adding first Controller class --- .../controllers/MeasurementController.java | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java new file mode 100644 index 0000000..63ae48a --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java @@ -0,0 +1,41 @@ +package com.oraclequantapi.oraclequantapi.controllers; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +public class MeasurementController { + @Autowired + public MeasurementService measurementService; + + // /convert-measurements?input=aa + @GetMapping(path = "/convert-measurements") + public ResponseEntity> convertMeasurements( + @RequestParam(name = "input", required = false) String input, + @RequestParam(name = "convert-measurements", required = false) String legacyInput, + HttpServletRequest request + ) { + + String selectedInput = input != null ? input : legacyInput; + List output = measurementService.convertAndSave(selectedInput, getSourceIpAddress(request)); + return ResponseEntity.status(HttpStatus.OK).body(output); + } + + // Get the real client IP when the app is behind a proxy; otherwise use remote address. + private String getSourceIpAddress(HttpServletRequest request) { + String forwardedFor = request.getHeader("X-Forwarded-For"); + + if (forwardedFor != null && !forwardedFor.isBlank()) { + return forwardedFor.split(",")[0].trim(); + } + + return request.getRemoteAddr(); + } +} From e2d7e7c456eaab23d6b5da4753b0dad79426ea3e Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:20:14 +0400 Subject: [PATCH 16/29] Adding second Controller class --- .../oraclequantapi/controllers/HistoryController.java | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java new file mode 100644 index 0000000..7b001e3 --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java @@ -0,0 +1,10 @@ +package com.oraclequantapi.oraclequantapi.controllers; + +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping (path = "/history") +public class HistoryController { + +} From b62f1eb5931e824adaf4c41ed25c78410b5fbf3c Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:20:48 +0400 Subject: [PATCH 17/29] Updating second Controller class --- .../controllers/HistoryController.java | 40 ++++++++++++++++++- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java index 7b001e3..7809eb7 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java @@ -1,10 +1,46 @@ package com.oraclequantapi.oraclequantapi.controllers; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @RequestMapping (path = "/history") public class HistoryController { + @Autowired + public HistoryService historyService; + + // Return all saved conversion requests from Oracle DB. + @GetMapping + public ResponseEntity> getAllHistory() { + return ResponseEntity.status(HttpStatus.OK).body(historyService.getHistory()); + } + + // Return one saved conversion request by id. + @GetMapping(path = "/{id}") + public ResponseEntity getSpecificHistory(@PathVariable String id) { + MeasurementHistory history = historyService.getHistoryById(id); + return ResponseEntity.status(HttpStatus.OK).body(history); + } + + // Update a history record by id. + @PutMapping(path = "/{id}") + public ResponseEntity updateHistory( + @PathVariable String id, + @RequestBody MeasurementHistory incomingHistory + ) { + MeasurementHistory history = historyService.updateHistory(id, incomingHistory); + return ResponseEntity.status(HttpStatus.OK).body(history); + } + + // Delete all saved history records. + @DeleteMapping + public ResponseEntity clearHistory() { + historyService.clearHistory(); + return ResponseEntity.status(HttpStatus.NO_CONTENT).build(); + } } From 2a94970b987e4c2ad9c8667c68aab5f51dcea646 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:22:13 +0400 Subject: [PATCH 18/29] Adding second service class --- .../oraclequantapi/services/MeasurementService.java | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java new file mode 100644 index 0000000..3259731 --- /dev/null +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java @@ -0,0 +1,8 @@ +package com.oraclequantapi.oraclequantapi.services; + +import org.springframework.stereotype.Service; + +@Service +public class MeasurementService { + +} From 62dd2ef8aeef7ff34cf4ed01a4b12d2a23c28dda Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:24:55 +0400 Subject: [PATCH 19/29] Updating service class --- .../oraclequantapi/services/MeasurementService.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java index 3259731..1561ccd 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java @@ -1,8 +1,12 @@ package com.oraclequantapi.oraclequantapi.services; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MeasurementService { + @Autowired + private HistoryService historyService; + } From faeb7f40a382e790b08ab3ff0905910acf69e3f0 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:25:02 +0400 Subject: [PATCH 20/29] Updating service class --- .../services/MeasurementService.java | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java index 1561ccd..9ffa257 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java @@ -1,7 +1,12 @@ package com.oraclequantapi.oraclequantapi.services; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; +import org.springframework.web.server.ResponseStatusException; + +import java.util.ArrayList; +import java.util.List; @Service public class MeasurementService { @@ -9,4 +14,94 @@ public class MeasurementService { @Autowired private HistoryService historyService; + // Main method used by the controller: convert the input, then save the request in Oracle DB. + public List convertAndSave(String input, String sourceIpAddress) { + MeasurementSequence sequence = getMeasurement(input); + List output = processMeasurement(sequence); + historyService.saveCurrentMeasurement(sourceIpAddress, sequence, output); + return output; + } + + // Build a MeasurementSequence object from the raw query parameter. + public MeasurementSequence getMeasurement(String givenInput) { + if (givenInput == null) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Query parameter 'input' is required."); + } + + MeasurementSequence sequence = new MeasurementSequence(givenInput); + + if (!sequence.isValid()) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Query parameter 'input' is required."); + } + + return sequence; + } + + // Converts the encoded string into package totals. + public List processMeasurement(MeasurementSequence sequence) { + String input = sequence.getValueAsString(); + List results = new ArrayList<>(); + int index = 0; + + while (index < input.length()) { + // Every package starts with an encoded count. + ReadResult countResult = readEncodedNumber(input, index); + long count = countResult.value; + index = countResult.nextIndex; + + long packageTotal = 0; + long valuesRead = 0; + + // Read up to "count" measurement values. If the string ends early, use what exists. + while (valuesRead < count && index < input.length()) { + ReadResult measurementResult = readEncodedNumber(input, index); + packageTotal = packageTotal + measurementResult.value; + index = measurementResult.nextIndex; + valuesRead++; + } + + results.add(packageTotal); + } + + return results; + } + + // Reads one encoded number. + // Examples: "_" = 0, "a" = 1, "z" = 26, "za" = 27, "zza" = 53. + private ReadResult readEncodedNumber(String input, int startIndex) { + long value = 0; + int index = startIndex; + + // Keep adding 26 for every z until the first non-z character appears. + while (index < input.length() && input.charAt(index) == 'z') { + value = value + 26; + index++; + } + + // If the input ended after z characters, return the total z value. + if (index >= input.length()) { + return new ReadResult(value, index); + } + + char current = input.charAt(index); + + if (current == '_') { + return new ReadResult(value, index + 1); + } + + value = value + (current - 'a' + 1); + return new ReadResult(value, index + 1); + } + + // Helper object that returns both the decoded value and the next reading position + private static class ReadResult { + public long value; + public int nextIndex; + + public ReadResult(long value, int nextIndex) { + this.value = value; + this.nextIndex = nextIndex; + } + } + } From 1a94572860acb03fadc87d1ac3179016fb3cb66e Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:29:35 +0400 Subject: [PATCH 21/29] Updating application properties --- src/main/resources/application.properties | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 99d0060..c6e93f4 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1 +1,13 @@ -spring.application.name=oraclequantapi +spring.application.name=litedesk-api + +# Oracle XE datasource +spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1 +spring.datasource.username=system +spring.datasource.password=29999login +spring.datasource.driver-class-name=oracle.jdbc.OracleDriver + +# JPA / Hibernate settings +# "update" creates/updates tables automatically — safe for development +spring.jpa.hibernate.ddl-auto=update +spring.jpa.database-platform=org.hibernate.dialect.OracleDialect +spring.jpa.show-sql=true From 2f50c4108081f7b1582e4cbd955251538335015e Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 12:54:00 +0400 Subject: [PATCH 22/29] Updating Maven pom.xml --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 3e0a3be..d866d3a 100644 --- a/pom.xml +++ b/pom.xml @@ -51,6 +51,7 @@ spring-boot-starter-test test + From 2db6361e73befb8365345d5255135c03cad504ca Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Thu, 21 May 2026 13:25:10 +0400 Subject: [PATCH 23/29] Enhancements --- ...rementsHistory.java => MeasurementHistory.java} | 2 +- ...mentsSequence.java => MeasurementSequence.java} | 14 ++++++++++++-- ...tory.java => MeasurementHistoryRepository.java} | 0 .../oraclequantapi/services/HistoryService.java | 6 ++++++ 4 files changed, 19 insertions(+), 3 deletions(-) rename src/main/java/com/oraclequantapi/oraclequantapi/models/{MeasurementsHistory.java => MeasurementHistory.java} (96%) rename src/main/java/com/oraclequantapi/oraclequantapi/models/{MeasurementsSequence.java => MeasurementSequence.java} (77%) rename src/main/java/com/oraclequantapi/oraclequantapi/repositories/{MeasurementRepository.java => MeasurementHistoryRepository.java} (100%) diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java similarity index 96% rename from src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java rename to src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java index b4cee40..3aa7c09 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java @@ -7,7 +7,7 @@ @Entity @Table(name = "MEASUREMENT_TABLE") -public class MeasurementsHistory { +public class MeasurementHistory { // UUID string @Id diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementSequence.java similarity index 77% rename from src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java rename to src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementSequence.java index 8b50fd8..9061125 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementsSequence.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementSequence.java @@ -3,11 +3,11 @@ import java.util.Locale; -public class MeasurementsSequence { +public class MeasurementSequence { public String value; - public MeasurementsSequence(String value){ + public MeasurementSequence(String value){ setValue(value); } @@ -21,6 +21,16 @@ private void setValue(String value) { } } + public String getValueAsString() { + return value; + } + + // After normalization, the value is valid as long as it is not null. + public boolean isValid() { + return value != null; + } + + private String normalize (String value){ String lowerValue = value.toLowerCase(Locale.ROOT); StringBuilder normalizedValue = new StringBuilder(); diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementRepository.java b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementHistoryRepository.java similarity index 100% rename from src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementRepository.java rename to src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementHistoryRepository.java diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java index af7647a..d87ab93 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java @@ -1,5 +1,6 @@ package com.oraclequantapi.oraclequantapi.services; +import com.oraclequantapi.oraclequantapi.models.MeasurementHistory; import com.oraclequantapi.oraclequantapi.repositories.MeasurementHistoryRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,6 +30,11 @@ public MeasurementHistory saveCurrentMeasurement( history.output = formatOutput(output); return measurementHistoryRepository.save(history); } + + public List getHistory() { + return measurementHistoryRepository.findAll(); + } + public MeasurementHistory getHistoryById(String id) { return measurementHistoryRepository.findById(id).orElse(null); } From 2a932668d30ccdb5cc7163a05f2fa639938be7ba Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Fri, 22 May 2026 17:58:54 +0400 Subject: [PATCH 24/29] Enhancements --- pom.xml | 6 ++++++ .../oraclequantapi/controllers/HistoryController.java | 2 ++ .../oraclequantapi/controllers/MeasurementController.java | 1 + .../repositories/MeasurementHistoryRepository.java | 2 +- .../oraclequantapi/services/HistoryService.java | 1 + .../oraclequantapi/services/MeasurementService.java | 1 + .../oraclequantapi/OraclequantapiApplicationTests.java | 7 +++++++ 7 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d866d3a..a659d74 100644 --- a/pom.xml +++ b/pom.xml @@ -52,6 +52,12 @@ test + + com.h2database + h2 + test + + diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java index 7809eb7..c1f4e3a 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/HistoryController.java @@ -1,5 +1,7 @@ package com.oraclequantapi.oraclequantapi.controllers; +import com.oraclequantapi.oraclequantapi.models.MeasurementHistory; +import com.oraclequantapi.oraclequantapi.services.HistoryService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java index 63ae48a..098c3d4 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java @@ -1,5 +1,6 @@ package com.oraclequantapi.oraclequantapi.controllers; +import com.oraclequantapi.oraclequantapi.services.MeasurementService; import jakarta.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementHistoryRepository.java b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementHistoryRepository.java index 7b01295..a4ca7d4 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementHistoryRepository.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/repositories/MeasurementHistoryRepository.java @@ -1,6 +1,6 @@ package com.oraclequantapi.oraclequantapi.repositories; -import om.oraclequant.pkc_api.models.MeasurementHistory; +import com.oraclequantapi.oraclequantapi.models.MeasurementHistory; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java index d87ab93..1863641 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/HistoryService.java @@ -1,6 +1,7 @@ package com.oraclequantapi.oraclequantapi.services; import com.oraclequantapi.oraclequantapi.models.MeasurementHistory; +import com.oraclequantapi.oraclequantapi.models.MeasurementSequence; import com.oraclequantapi.oraclequantapi.repositories.MeasurementHistoryRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java index 9ffa257..684a35c 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/services/MeasurementService.java @@ -1,5 +1,6 @@ package com.oraclequantapi.oraclequantapi.services; +import com.oraclequantapi.oraclequantapi.models.MeasurementSequence; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; diff --git a/src/test/java/com/oraclequantapi/oraclequantapi/OraclequantapiApplicationTests.java b/src/test/java/com/oraclequantapi/oraclequantapi/OraclequantapiApplicationTests.java index 2de285b..fd1f606 100644 --- a/src/test/java/com/oraclequantapi/oraclequantapi/OraclequantapiApplicationTests.java +++ b/src/test/java/com/oraclequantapi/oraclequantapi/OraclequantapiApplicationTests.java @@ -1,9 +1,16 @@ package com.oraclequantapi.oraclequantapi; import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; @SpringBootTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY) +@TestPropertySource(properties = { + "spring.jpa.database-platform=org.hibernate.dialect.H2Dialect", + "spring.jpa.hibernate.ddl-auto=update" +}) class OraclequantapiApplicationTests { @Test From 0f1703e5d658bcb565565fdd838fa635faa0e7af Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Sun, 24 May 2026 17:50:18 +0400 Subject: [PATCH 25/29] Enhancements --- pom.xml | 2 +- .../oraclequantapi/controllers/MeasurementController.java | 4 ++-- .../oraclequantapi/models/MeasurementHistory.java | 1 + src/main/resources/application.properties | 4 +++- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index a659d74..d8f7b08 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.oraclequantapi oraclequantapi - 0.0.1-SNAPSHOT + 1.0.0 diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java index 098c3d4..f834454 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/controllers/MeasurementController.java @@ -17,10 +17,10 @@ public class MeasurementController { public MeasurementService measurementService; // /convert-measurements?input=aa - @GetMapping(path = "/convert-measurements") + @GetMapping(path = "/convert") public ResponseEntity> convertMeasurements( @RequestParam(name = "input", required = false) String input, - @RequestParam(name = "convert-measurements", required = false) String legacyInput, + @RequestParam(name = "convert", required = false) String legacyInput, HttpServletRequest request ) { diff --git a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java index 3aa7c09..e4e7341 100644 --- a/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java +++ b/src/main/java/com/oraclequantapi/oraclequantapi/models/MeasurementHistory.java @@ -25,6 +25,7 @@ public class MeasurementHistory { // Normalized input string after converting capital letters to lowercase. + // Lob: Large Object & No size limit @Lob @Column(name = "MEASUREMENT_INPUT") public String input; diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index c6e93f4..b9bdd50 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,4 +1,4 @@ -spring.application.name=litedesk-api +spring.application.name=oraclequant-api # Oracle XE datasource spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1 @@ -6,6 +6,8 @@ spring.datasource.username=system spring.datasource.password=29999login spring.datasource.driver-class-name=oracle.jdbc.OracleDriver +server.address=0.0.0.0 + # JPA / Hibernate settings # "update" creates/updates tables automatically — safe for development spring.jpa.hibernate.ddl-auto=update From cae34dd210f77047cd6d3b7173af921a2ee65cc2 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Sun, 24 May 2026 19:52:53 +0400 Subject: [PATCH 26/29] Enhancements --- src/main/resources/application.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index b9bdd50..2db64b5 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,7 +1,7 @@ spring.application.name=oraclequant-api # Oracle XE datasource -spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1 +spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/XEPDB1 spring.datasource.username=system spring.datasource.password=29999login spring.datasource.driver-class-name=oracle.jdbc.OracleDriver From d058dfb76471b981467ea1025a61e70dac918d17 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Mon, 25 May 2026 17:30:16 +0400 Subject: [PATCH 27/29] Update application properties --- src/main/resources/application.properties | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2db64b5..de13d21 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,12 +1,11 @@ spring.application.name=oraclequant-api # Oracle XE datasource -spring.datasource.url=jdbc:oracle:thin:@//localhost:1521/XEPDB1 +spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1 spring.datasource.username=system spring.datasource.password=29999login spring.datasource.driver-class-name=oracle.jdbc.OracleDriver -server.address=0.0.0.0 # JPA / Hibernate settings # "update" creates/updates tables automatically — safe for development From b78492b41377a3b2a457caa74ff49d47254b4f40 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Mon, 25 May 2026 20:22:58 +0400 Subject: [PATCH 28/29] Update README.md file --- README.md | 314 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 253 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index b1cccfd..a4beeac 100644 --- a/README.md +++ b/README.md @@ -1,61 +1,253 @@ -## Submission Instructions - -To submit your Oracle JAVA Spring Boot Maven project as a solution, please follow these steps: - -### Step 1: Install git on your PC -- Install "git" as shown in this tutorial: [How to install git](https://youtu.be/iYkLrXobBbA?si=_l0haibv_X9NpIjJ) -- Open command prompt and run - ```bash - git version - ``` -- If you see the version, then git is successfully installed. - -### Step 2: Fork the Repository -- Navigate to [this repository](https://github.com/CodelineAtyab/oraclequantapi) provided by Codeline. -- Click on the "Fork" button at the top-right corner of the page to create a copy of the repository under your own GitHub account. - -### Step 3: Clone the Forked Repository -- Open your terminal or command prompt. -- Clone the forked repository to your local machine using the following command: - ```bash - git clone https://github.com/your-username/repo-name.git - ``` - -### Step 4: Create a new branch -- Navigate to the cloned repository directory - ```bash - cd repo-name - ``` -- Create a new branch for your code submissions (Replace your-name with your name in your-name-submission-branch): - ```bash - git checkout -b your-name-submission-branch - ``` - - -### Step 5: Add Your Code -- Implement the API - -### Step 6: Commit your changes -- Run the following commands in order to commit your changes: - ```bash - git add * - git commit -m "Meaningful commit message here" - ``` - -### Step 7: Push Your Branch to GitHub -- Run the following commands to upload the changes to the forked github repository (Replace your-name with your name in your-name-submission-branch): - ```bash - git push origin your-name-submission-branch - ``` - -### Step 8: Create a Pull Request -- Go to your forked repository on GitHub. -- You should see a prompt to create a pull request. Click on "Compare & pull request". -- Provide a title and description for your pull request, then click "Create pull request". - -### Step 9: Notify Codeline -- Notify on slack that you have created a PR for your solution. - -## Note: If you face any issues in the process above, Please do the following: -- Watch [this youtube tutorial](https://www.youtube.com/watch?v=a_FLqX3vGR4) -- Contact Ikhlas or Atyab. +# OracleQuant ERP - Package Measurement Conversion API + +Trainer-style Spring Boot API for converting encoded package measurement strings into package inflow totals. The application uses Java 17, Spring Boot, Maven, Spring Data JPA, and Oracle XE. + +## Features + +- `GET /convert-measurements` converts encoded measurement input into a JSON array. +- Conversion history is stored in Oracle XE through Spring Data JPA. +- History can be fetched, updated, and cleared through REST endpoints. +- Console logs and rolling file logs are enabled. +- Log files keep one week of history. +- `CHANGELOG.md` and `version.txt` track released features. + +## Project Structure + +```text +src/main/java/om/oraclequant/pkc_api/OracleQuantPkcApiApplication.java +src/main/java/om/oraclequant/pkc_api/controllers/MeasurementController.java +src/main/java/om/oraclequant/pkc_api/controllers/HistoryController.java +src/main/java/om/oraclequant/pkc_api/services/MeasurementService.java +src/main/java/om/oraclequant/pkc_api/services/HistoryService.java +src/main/java/om/oraclequant/pkc_api/models/MeasurementSequence.java +src/main/java/om/oraclequant/pkc_api/models/MeasurementHistory.java +src/main/java/om/oraclequant/pkc_api/repositories/MeasurementHistoryRepository.java +src/main/resources/application.properties +src/main/resources/logback-spring.xml +CHANGELOG.md +version.txt +``` + +## Conversion Rules + +- `a` to `z` represent `1` to `26`. +- `_` represents `0`. +- Uppercase letters are converted to lowercase. +- Characters other than letters and `_` are converted to `_`, so they count as zero. +- A sequence of `z` characters continues until the first non-`z` character. +- Each package starts with an encoded count, then up to that many encoded measurement values. +- If the count asks for more values than remain, the package uses only the remaining values. + +Examples: + +```text +aa -> [1] +abbcc -> [2, 6] +dz_a_aazzaaa -> [28, 53, 1] +a_ -> [0] +abcdabcdab -> [2, 7, 7] +abcdabcdab_ -> [2, 7, 7, 0] +zdaaaaaaaabaaaaaaaabaaaaaaaabbaa -> [34] +za_a_a_a_a_a_a_a_a_a_a_a_a_azaaa -> [40, 1] +a1 -> [0] +``` + +## Database Configuration + +The application is configured for Oracle XE using Oracle Thin JDBC. + +Edit `src/main/resources/application.properties`: + +```properties +spring.datasource.url=jdbc:oracle:thin:@localhost:1521/XEPDB1 +spring.datasource.username=your_username +spring.datasource.password=your_password +spring.datasource.driver-class-name=oracle.jdbc.OracleDriver + +spring.jpa.hibernate.ddl-auto=update +spring.jpa.database-platform=org.hibernate.dialect.OracleDialect +spring.jpa.show-sql=true +``` + +For Oracle XE, the common service name is: + +```text +XEPDB1 +``` + +If your Oracle installation uses SID instead, the URL may look like: + +```properties +spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE +``` + +## Running The Application + +From the project root: + +```bash +./mvnw spring-boot:run +``` + +Or build and run the jar: + +```bash +./mvnw clean package +java -jar target/pkc-api.jar +``` + +The API runs on: + +```text +http://localhost:8080 +``` + +## REST API Endpoints + +Convert measurements: + +```bash +curl 'http://localhost:8080/convert?input=aa' +``` + +Response: + +```json +[1] +``` + +The older query parameter name is also supported: + +```bash +curl 'http://localhost:8080/convert?convert=aa' +``` + +Get all history records: + +```bash +curl 'http://localhost:8080/history' +``` + +Get one history record: + +```bash +curl 'http://localhost:8080/history/{id}' +``` + +Update one history record: + +```bash +curl -X PUT 'http://localhost:8080/history/{id}' \ + -H 'Content-Type: application/json' \ + -d '{"input":"aa","output":"[1]"}' +``` + +Clear all history: + +```bash +curl -X DELETE 'http://localhost:8080/history' +``` + +## Logging + +Logs are printed to the console and written to: + +```text +logs/pkc-api.log +``` + +Rolling logs are configured in: + +```text +src/main/resources/logback-spring.xml +``` + +The log policy keeps seven days of daily compressed log files: + +```text +logs/pkc-api.log.2026-05-25.gz +logs/pkc-api.log.2026-05-24.gz +... +``` + +## Local No-Database Test + +Before connecting Oracle, the conversion logic can be tested locally with: + +```text +local-test/MeasurementLocalTest.java +``` + +This runner checks the conversion rules without starting Spring Boot and without using Oracle. + +## Deploy On Oracle Linux Via SSH + +Build the jar locally: + +```bash +./mvnw clean package +``` + +Copy the jar to Oracle Linux: + +```bash +scp target/pkc-api.jar opc@your-server-ip:/home/opc/pkc-api.jar +``` + +SSH into the Oracle Linux server: + +```bash +ssh opc@your-server-ip +``` + +Install Java 17 if needed: + +```bash +sudo dnf install -y java-17-openjdk +``` + +Set database environment values or edit `application.properties` before building: + +```bash +export ORACLE_DB_URL='jdbc:oracle:thin:@localhost:1521/XEPDB1' +export ORACLE_DB_USERNAME='your_username' +export ORACLE_DB_PASSWORD='your_password' +``` + +Run the jar: + +```bash +java -jar /home/opc/pkc-api.jar +``` + +Optional systemd service: + +```ini +[Unit] +Description=OracleQuant Package Measurement API +After=network.target + +[Service] +User=opc +WorkingDirectory=/home/opc +ExecStart=/usr/bin/java -jar /home/opc/pkc-api.jar +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +Save it as: + +```text +/etc/systemd/system/pkc-api.service +``` + +Then run: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now pkc-api +sudo systemctl status pkc-api +``` \ No newline at end of file From 055c7e8e82be6b295178639edb1ae1a59d05a4b8 Mon Sep 17 00:00:00 2001 From: Ibrahim Alrahbi Date: Mon, 25 May 2026 20:34:35 +0400 Subject: [PATCH 29/29] Update README.md file --- README.md | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/README.md b/README.md index a4beeac..57bed41 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # OracleQuant ERP - Package Measurement Conversion API -Trainer-style Spring Boot API for converting encoded package measurement strings into package inflow totals. The application uses Java 17, Spring Boot, Maven, Spring Data JPA, and Oracle XE. +Trainer-style Spring Boot API for converting encoded package measurement strings into package inflow totals. The application uses Java 17, Spring Boot, Maven, Oracle Linux, and Oracle XE. ## Features @@ -9,7 +9,6 @@ Trainer-style Spring Boot API for converting encoded package measurement strings - History can be fetched, updated, and cleared through REST endpoints. - Console logs and rolling file logs are enabled. - Log files keep one week of history. -- `CHANGELOG.md` and `version.txt` track released features. ## Project Structure @@ -23,8 +22,6 @@ src/main/java/om/oraclequant/pkc_api/models/MeasurementSequence.java src/main/java/om/oraclequant/pkc_api/models/MeasurementHistory.java src/main/java/om/oraclequant/pkc_api/repositories/MeasurementHistoryRepository.java src/main/resources/application.properties -src/main/resources/logback-spring.xml -CHANGELOG.md version.txt ``` @@ -148,28 +145,6 @@ Clear all history: curl -X DELETE 'http://localhost:8080/history' ``` -## Logging - -Logs are printed to the console and written to: - -```text -logs/pkc-api.log -``` - -Rolling logs are configured in: - -```text -src/main/resources/logback-spring.xml -``` - -The log policy keeps seven days of daily compressed log files: - -```text -logs/pkc-api.log.2026-05-25.gz -logs/pkc-api.log.2026-05-24.gz -... -``` - ## Local No-Database Test Before connecting Oracle, the conversion logic can be tested locally with: