Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions README2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# oraclequantapi- Measurement Parser API

A Spring Boot REST API that parses encoded measurement strings and stores the history in an Oracle XE database.

---

## How to Run

1. Start Oracle XE:

run the docker start oracle-xe


2. Build the JAR:
-----
./mvnw clean package
-----
3. Run the app:
------
java -jar target/oraclequantapi-0.0.1.jar
------
4. Open the browser and test:
------
http://localhost:8080/convert-measurements?input=abbcc
------

......................

## How to Deploy to Oracle Linux VM

1. Copy the JAR to the VM:
-------
scp target/oraclequantapi-0.0.1 safa@<vm-ip>:~/
-------

2. SSH into the VM:
-------
ssh safa@<vm-ip>
-------

3. Run the app:
-------
java -jar ~/tryout-0.0.1-SNAPSHOT.jar
-------

4. Test from your browser:
-------
http://<vm-ip>:8080/convert-measurements?input=abbcc
-------

.......................

## How to Configure the Database

Open `src/main/resources/application.properties` and update these values:

```properties
spring.datasource.url=jdbc:oracle:thin:@<host>:1521/XEPDB1
spring.datasource.username=system
spring.datasource.password=<your-password>
```

- Replace `<host>` with `localhost` if running locally, or your Mac IP if running from the VM
- Replace `<your-password>` with the password you set when creating the Oracle XE container

.........................

## API Endpoints

| GET | `/convert-measurements?input=<string>` | Parse input and return result |
| GET | `/history` | Get all history records |
| GET | `/history/{id}` | Get one record by ID |
| PUT | `/history/{id}` | Update a record by ID |
| DELETE | `/history` | Clear all history records|

### Examples

**Convert:**
```
GET http://localhost:8080/convert-measurements?input=abbcc
Response: [2, 6]
```

**Get all history:**
```
GET http://localhost:8080/history
```

**Get one record:**
```
GET http://localhost:8080/history/1
```

**Update a record:**
```
PUT http://localhost:8080/history/1
Body: { "input": "abbcc" }
```

**Clear history:**
```
DELETE http://localhost:8080/history
Response: History has been Deleted
```

13 changes: 12 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
</parent>
<groupId>com.oraclequantapi</groupId>
<artifactId>oraclequantapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<version>0.0.1</version>
<name/>
<description/>
<url/>
Expand Down Expand Up @@ -40,6 +40,17 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc11</artifactId>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.oraclequantapi.oraclequantapi.controller;
import com.oraclequantapi.oraclequantapi.model.MeasurementRecord;
import com.oraclequantapi.oraclequantapi.service.HistoryService;
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;
import java.util.Map;

@RestController
// All endpoints in this class start with "/history"
@RequestMapping(path = "/history")
public class HistoryController {

@Autowired
public HistoryService historyService;
//Returns all history records from the database as a JSON array
@GetMapping
public ResponseEntity<List<MeasurementRecord>> getAll() {
return ResponseEntity.status(HttpStatus.OK).body(historyService.getAll());
}
//Returns a specific record by its ID
@GetMapping(path = "/{id}")
public ResponseEntity<MeasurementRecord> getById(@PathVariable long id) {
return historyService.getById(id)
.map(record -> ResponseEntity.status(HttpStatus.OK).body(record))
.orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).build());
}
//update input by specific ID
@PutMapping(path = "/{id}")
public ResponseEntity<MeasurementRecord> update(@PathVariable long id,
@RequestBody Map<String, String> body) {
String newInput = body.get("input");
return historyService.update(id, newInput)
.map(record -> ResponseEntity.status(HttpStatus.OK).body(record))
.orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).build());
}
//Delete all the records
@DeleteMapping
public ResponseEntity<String> clearAll() {
historyService.clearAll();
return ResponseEntity.status(HttpStatus.OK).body("History has been Deleted");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.oraclequantapi.oraclequantapi.controller;
import jakarta.servlet.http.HttpServletRequest;
import com.oraclequantapi.oraclequantapi.model.MeasurementRecord;
import com.oraclequantapi.oraclequantapi.service.HistoryService;
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 = "/convert-measurements")
public class MeasurementController {

@Autowired
public HistoryService historyService;

@GetMapping
public ResponseEntity<List<Long>> convertMeasurements(@RequestParam("input") String input,
HttpServletRequest request) {
MeasurementRecord record = historyService.save(input, request.getRemoteAddr());
return ResponseEntity.status(HttpStatus.OK).body(record.getOutput());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.oraclequantapi.oraclequantapi.model;
import jakarta.persistence.*;
import java.time.LocalDateTime;
import java.util.List;

@Entity
@Table(name = "measurement_records")
public class MeasurementRecord {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private long id;

private LocalDateTime timestamp;
private String sourceIpAddress;
private String input;

@ElementCollection
@CollectionTable(name = "measurement_output", joinColumns = @JoinColumn(name = "record_id"))
@OrderColumn(name = "output_index")
@Column(name = "output_value")
private List<Long> output;

public MeasurementRecord() {}

public MeasurementRecord(long id, LocalDateTime timestamp, String sourceIpAddress, String input, List<Long> output) {
this.id = id;
this.timestamp = timestamp;
this.sourceIpAddress = sourceIpAddress;
this.input = input;
this.output = output;
}

public long getId() { return id; }

public LocalDateTime getTimestamp() { return timestamp; }

public String getSourceIpAddress() { return sourceIpAddress; }

public String getInput() { return input; }
public void setInput(String input) { this.input = input; }

public List<Long> getOutput() { return output; }
public void setOutput(List<Long> output) { this.output = output; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.oraclequantapi.oraclequantapi.repository;

import com.oraclequantapi.oraclequantapi.model.MeasurementRecord;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface MeasurementRecordRepository extends JpaRepository<MeasurementRecord, Long> {
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.oraclequantapi.oraclequantapi.service;
import com.oraclequantapi.oraclequantapi.model.MeasurementRecord;
import com.oraclequantapi.oraclequantapi.repository.MeasurementRecordRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
public class HistoryService {

@Autowired
private MeasurementRecordRepository measurementRecordRepository;

@Autowired
private MeasurementParser measurementParser;

public MeasurementRecord save(String input, String sourceIp) {
List<Long> output = measurementParser.parse(input);
MeasurementRecord record = new MeasurementRecord(
0,
LocalDateTime.now(),
sourceIp,
input,
output
);
return measurementRecordRepository.save(record);
}

public List<MeasurementRecord> getAll() {
return measurementRecordRepository.findAll();
}

public Optional<MeasurementRecord> getById(long id) {
return measurementRecordRepository.findById(id);
}

public Optional<MeasurementRecord> update(long id, String newInput) {
Optional<MeasurementRecord> record = measurementRecordRepository.findById(id);
record.ifPresent(r -> {
r.setInput(newInput);
r.setOutput(measurementParser.parse(newInput));
measurementRecordRepository.save(r);
});
return record;
}

public void clearAll() {
measurementRecordRepository.deleteAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.oraclequantapi.oraclequantapi.service;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;

@Service
public class MeasurementParser {

public List<Long> parse(String input) {
List<Long> packageTotals = new ArrayList<>();
int i = 0;

while (i < input.length()) {

// Step 1: read cycleCount
int cycleCount = 0;
while (i < input.length()) {
char c = input.charAt(i);
i++;
if (c == 'z') {
cycleCount += 26;
} else {
cycleCount += charValue(c);
break;
}
}

// Step 2: read values and sum them
long packageTotal = 0;
for (int v = 0; v < cycleCount; v++) {
if (i >= input.length()) break;

long value = 0;
while (i < input.length()) {
char c = input.charAt(i);
i++;
if (c == 'z') {
value += 26;
} else {
value += charValue(c);
break;
}
}
packageTotal += value;
}

packageTotals.add(packageTotal);
}

return packageTotals;
}

private int charValue(char c) {
if (c == '_') return 0;
return c - 'a' + 1; // a=1, b=2, ..., z=26
}
}
11 changes: 11 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
spring.application.name=oraclequantapi

# 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
spring.jpa.database-platform=org.hibernate.dialect.OracleDialect
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
7 changes: 7 additions & 0 deletions version.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
v0.0.1 - 2026-05-24
- Added GET /convert-measurements endpoint to parse measurement input string
- Added history tracking with Oracle XE database
- Added GET /history to retrieve all history records
- Added GET /history/{id} to retrieve a specific history record
- Added PUT /history/{id} to update a history record
- Added DELETE /history to clear all history records