Skip to content

Commit ed72c70

Browse files
committed
update to spring 3.3.1 and add upload/download file functions
1 parent 8dd5d5d commit ed72c70

File tree

11 files changed

+258
-48
lines changed

11 files changed

+258
-48
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ MISSING
1515
MISSING
1616

1717
## Notes/Issues
18-
MISSING
18+
Spring Boot 3.0 requires Java 17 as a minimum version.
1919

2020
## URLs
2121
https://apexapps.oracle.com/pls/apex/r/dbpm/livelabs/view-workshop?wid=3874

pom.xml

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
44
<modelVersion>4.0.0</modelVersion>
55
<parent>
66
<groupId>org.springframework.boot</groupId>
77
<artifactId>spring-boot-starter-parent</artifactId>
8-
<version>3.1.4</version>
8+
<version>3.3.1</version>
99
<relativePath/>
1010
</parent>
1111
<groupId>oracleai</groupId>
@@ -15,26 +15,13 @@
1515
<description>Oracle AI Demos</description>
1616

1717
<properties>
18-
<spring-cloud.version>2021.0.5</spring-cloud.version>
19-
<oracle.jdbc.version>21.7.0.0</oracle.jdbc.version>
20-
<spring.boot.version>3.1.2</spring.boot.version>
21-
<snakeyaml.version>1.31</snakeyaml.version>
22-
<spring.vault.version>3.1.1</spring.vault.version>
23-
<oci.sdk.version>3.29.0</oci.sdk.version>
24-
<jib-maven-plugin.version>3.3.1</jib-maven-plugin.version>
25-
<liquibase.version>4.17.2</liquibase.version>
18+
<oci.sdk.version>3.44.2</oci.sdk.version>
2619
</properties>
2720

2821
<dependencies>
2922
<dependency>
3023
<groupId>org.springframework.boot</groupId>
3124
<artifactId>spring-boot-starter-web</artifactId>
32-
<exclusions>
33-
<exclusion>
34-
<groupId>org.yaml</groupId>
35-
<artifactId>snakeyaml</artifactId>
36-
</exclusion>
37-
</exclusions>
3825
</dependency>
3926
<dependency>
4027
<groupId>org.springframework.boot</groupId>
@@ -45,11 +32,10 @@
4532
<artifactId>json</artifactId>
4633
<version>20231013</version>
4734
</dependency>
48-
4935
<dependency>
50-
<groupId>com.oracle.oci.sdk</groupId>
51-
<artifactId>oci-java-sdk-common</artifactId>
52-
<version>${oci.sdk.version}</version>
36+
<groupId>com.oracle.cloud.spring</groupId>
37+
<artifactId>spring-cloud-oci-starter</artifactId>
38+
<version>1.0.0</version>
5339
</dependency>
5440
<dependency>
5541
<groupId>com.oracle.oci.sdk</groupId>
@@ -59,7 +45,7 @@
5945
<dependency>
6046
<groupId>com.oracle.oci.sdk</groupId>
6147
<artifactId>oci-java-sdk-generativeaiinference</artifactId>
62-
<version>3.32.1</version>
48+
<version>${oci.sdk.version}</version>
6349
</dependency>
6450
<dependency>
6551
<groupId>com.oracle.oci.sdk</groupId>
@@ -87,20 +73,6 @@
8773
<artifactId>slf4j-simple</artifactId>
8874
<version>2.0.6</version>
8975
</dependency>
90-
<dependency>
91-
<groupId>org.springframework.boot</groupId>
92-
<artifactId>spring-boot-starter-web</artifactId>
93-
<version>${spring.boot.version}</version>
94-
</dependency>
95-
<dependency>
96-
<groupId>org.springframework.boot</groupId>
97-
<artifactId>spring-boot-starter-test</artifactId>
98-
<version>${spring.boot.version}</version>
99-
<scope>test</scope>
100-
</dependency>
101-
102-
103-
10476
<dependency>
10577
<groupId>javax.xml.bind</groupId>
10678
<artifactId>jaxb-api</artifactId>
@@ -122,18 +94,7 @@
12294
<artifactId>service</artifactId>
12395
<version>0.12.0</version>
12496
</dependency>
125-
</dependencies>
126-
<dependencyManagement>
127-
<dependencies>
128-
<dependency>
129-
<groupId>org.springframework.cloud</groupId>
130-
<artifactId>spring-cloud-dependencies</artifactId>
131-
<version>${spring-cloud.version}</version>
132-
<type>pom</type>
133-
<scope>import</scope>
134-
</dependency>
135-
</dependencies>
136-
</dependencyManagement>
97+
</dependencies>
13798
<build>
13899
<plugins>
139100
<plugin>

sql/aiuser-tables-indexes-functions.sql

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,3 +179,54 @@ BEGIN
179179
COMMIT;
180180
END;
181181
/
182+
183+
184+
CREATE TABLE image_store (
185+
id NUMBER GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
186+
image BLOB,
187+
image_name VARCHAR2(100)
188+
)
189+
/
190+
191+
create or replace PROCEDURE insert_image(p_image_name IN VARCHAR2, p_image BLOB) IS
192+
BEGIN
193+
INSERT INTO image_store (image_name, image) VALUES (p_image_name, p_image);
194+
END;
195+
/
196+
197+
BEGIN
198+
ORDS.ENABLE_OBJECT(
199+
P_ENABLED => TRUE,
200+
P_SCHEMA => 'AIUSER',
201+
P_OBJECT => 'INSERT_IMAGE',
202+
P_OBJECT_TYPE => 'PROCEDURE',
203+
P_OBJECT_ALIAS => 'insert_image',
204+
P_AUTO_REST_AUTH => FALSE
205+
);
206+
COMMIT;
207+
END;
208+
/
209+
210+
--curl --location --request POST \
211+
--'https://yourORDSendpoint.adb.us-ashburn-1.oraclecloudapps.com/ords/aiuser/insert_image/' \
212+
----header 'Content-Type: application/json' \
213+
----data-binary '{
214+
-- "p_image_name": "<VALUE>",
215+
-- "p_image": "<VALUE>"
216+
--}'
217+
218+
BEGIN
219+
ORDS.ENABLE_OBJECT(
220+
P_ENABLED => TRUE,
221+
P_SCHEMA => 'AIUSER',
222+
P_OBJECT => 'IMAGE_STORE',
223+
P_OBJECT_TYPE => 'TABLE',
224+
P_OBJECT_ALIAS => 'image_store',
225+
P_AUTO_REST_AUTH => FALSE
226+
);
227+
COMMIT;
228+
END;
229+
/
230+
231+
--curl --location \
232+
--'https://yourORDSendpoint.adb.us-ashburn-1.oraclecloudapps.com/ords/aiuser/image_store/'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package oracleai;
2+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
5+
@JsonIgnoreProperties(ignoreUnknown = true)
6+
public class ImageStore {
7+
private Long id;
8+
9+
@JsonProperty("image_name")
10+
private String imageName;
11+
12+
@JsonProperty("image") // Assuming the BLOB is mapped to this field
13+
private String imageBase64;
14+
15+
public Long getId() {
16+
return id;
17+
}
18+
19+
public void setId(Long id) {
20+
this.id = id;
21+
}
22+
23+
public String getImageName() {
24+
return imageName;
25+
}
26+
27+
public void setImageName(String imageName) {
28+
this.imageName = imageName;
29+
}
30+
31+
public String getImageBase64() {
32+
return imageBase64;
33+
}
34+
35+
public void setImageBase64(String imageBase64) {
36+
this.imageBase64 = imageBase64;
37+
}
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package oracleai;
2+
3+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
4+
import java.util.List;
5+
6+
@JsonIgnoreProperties(ignoreUnknown = true)
7+
public class ImageStoreWrapper {
8+
private List<ImageStore> items;
9+
10+
public List<ImageStore> getItems() {
11+
return items;
12+
}
13+
14+
public void setItems(List<ImageStore> items) {
15+
this.items = items;
16+
}
17+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package oracleai;
2+
3+
4+
import oracleai.services.ORDSCalls;
5+
import org.springframework.stereotype.Controller;
6+
import org.springframework.ui.Model;
7+
import org.springframework.web.bind.annotation.GetMapping;
8+
import org.springframework.web.bind.annotation.PostMapping;
9+
import org.springframework.web.bind.annotation.RequestMapping;
10+
import org.springframework.web.bind.annotation.RequestParam;
11+
import org.springframework.web.multipart.MultipartFile;
12+
13+
@Controller
14+
@RequestMapping("/transferimage")
15+
public class UploadDownloadImage {
16+
17+
@PostMapping("/uploadimage")
18+
public String uploadImage(@RequestParam("image") MultipartFile image, Model model) {
19+
ORDSCalls.uploadImage(image);
20+
System.out.println("Image upload complete for: " + image.getOriginalFilename());
21+
ImageStore[] imageStores = ORDSCalls.getImageStoreData();
22+
model.addAttribute("images", imageStores);
23+
return "images";
24+
}
25+
26+
27+
28+
@GetMapping("/downloadimages")
29+
public String getImageStoreData(Model model) {
30+
ImageStore[] imageStores = ORDSCalls.getImageStoreData();
31+
model.addAttribute("images", imageStores);
32+
return "images";
33+
}
34+
}

src/main/java/oracleai/services/ORDSCalls.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package oracleai.services;
22

3+
import oracleai.AIApplication;
4+
import oracleai.ImageStore;
5+
import oracleai.ImageStoreWrapper;
36
import org.jetbrains.annotations.Nullable;
47
import org.springframework.http.*;
58
import org.springframework.stereotype.Service;
@@ -8,6 +11,8 @@
811

912
import java.util.Base64;
1013
import java.util.Collections;
14+
import java.util.HashMap;
15+
import java.util.Map;
1116

1217
@Service
1318
public class ORDSCalls {
@@ -66,6 +71,37 @@ private static String callTextSearch(String ordsEndpoint, String jsonPayload) {
6671
return response.getBody();
6772
}
6873

74+
public static ResponseEntity<String> uploadImage(MultipartFile image) {
75+
try {
76+
String base64Image = Base64.getEncoder().encodeToString(image.getBytes());
77+
Map<String, String> payload = new HashMap<>();
78+
payload.put("p_image_name", image.getOriginalFilename());
79+
payload.put("p_image", base64Image);
80+
HttpHeaders headers = new HttpHeaders();
81+
headers.setContentType(MediaType.APPLICATION_JSON);
82+
HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(payload, headers);
83+
RestTemplate restTemplate = new RestTemplate();
84+
String uploadUrl = AIApplication.ORDS_ENDPOINT_URL + "insert_image/";
85+
return restTemplate.exchange(uploadUrl, HttpMethod.POST, requestEntity, String.class);
86+
} catch (Exception e) {
87+
throw new RuntimeException("Failed to upload image", e);
88+
}
89+
}
90+
6991

92+
public static ImageStore[] getImageStoreData() {
93+
String url = AIApplication.ORDS_ENDPOINT_URL + "image_store/";
94+
RestTemplate restTemplate = new RestTemplate();
95+
ResponseEntity<ImageStoreWrapper> response = restTemplate.getForEntity(url, ImageStoreWrapper.class);
96+
ImageStoreWrapper wrapper = response.getBody();
97+
if (wrapper != null) {
98+
for (ImageStore imageStore : wrapper.getItems()) {
99+
System.out.println("Image Name: " + imageStore.getImageName());
100+
}
101+
return wrapper.getItems().toArray(new ImageStore[0]);
102+
} else {
103+
return new ImageStore[0];
104+
}
105+
}
70106
}
71107

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Upload Image</title>
6+
</head>
7+
<body>
8+
<h1>Upload Image</h1>
9+
<form method="GET" action="/transferimage/downloadimages" >
10+
<button type="submit">Upload</button>
11+
</form>
12+
</body>
13+
</html>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<title>Upload Image</title>
6+
</head>
7+
<body>
8+
<h1>Upload Image</h1>
9+
<form method="POST" action="/transferimage/uploadimage" enctype="multipart/form-data">
10+
<label for="image">Select image:</label>
11+
<input type="file" id="image" name="image" accept="image/*" required>
12+
<button type="submit">Upload</button>
13+
</form>
14+
</body>
15+
</html>

src/main/resources/static/sidebar.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<a href="/ObjectDetectionGenAIAndSentimentAnalysis.html" class="w3-bar-item w3-button">Object Detection, Text Generation, and Sentiment Analysis</a><br>
44
<a href="/FaceRecognition.html" class="w3-bar-item w3-button">Face Recognition</a><br>
55
<a href="/TextSearch.html" class="w3-bar-item w3-button">Database Text Search and DBMS_SEARCH</a><br>
6+
<a href="/UploadImage.html" class="w3-bar-item w3-button">Upload Image</a><br>
7+
<a href="/DownloadImage.html" class="w3-bar-item w3-button">Download Images</a><br>
68
<a class="w3-bar-item w3-button">Video Analysis (coming soon)</a><br>
79
<a class="w3-bar-item w3-button">Speech Transcription And Translation (coming soon)</a><br>
810
<a class="w3-bar-item w3-button">Realtime Speech Transcription (coming soon)</a><br>

0 commit comments

Comments
 (0)