Skip to content
Draft
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
43 changes: 22 additions & 21 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,48 +1,49 @@
services:
# Oracle Database service
oracle-db:
image: container-registry.oracle.com/database/express:21.3.0-xe
container_name: photoalbum-oracle
# PostgreSQL Database service
# Migrated from Oracle to PostgreSQL - replaced Oracle container with PostgreSQL container
postgres-db:
image: postgres:15-alpine
container_name: photoalbum-postgres
environment:
- ORACLE_PWD=photoalbum
- ORACLE_CHARACTERSET=AL32UTF8
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=photoalbum
- POSTGRES_DB=postgres
ports:
- "1521:1521"
- "5500:5500"
- "5432:5432"
volumes:
- oracle_data:/opt/oracle/oradata
- ./oracle-init:/opt/oracle/scripts/startup
- postgres_data:/var/lib/postgresql/data
- ./postgres-init:/docker-entrypoint-initdb.d
networks:
- photoalbum-network
healthcheck:
test: ["CMD-SHELL", "echo 'SELECT 1 FROM DUAL;' | sqlplus -s photoalbum/photoalbum@//localhost:1521/XE || exit 1"]
interval: 30s
timeout: 10s
retries: 15
start_period: 180s
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s

# Photo Album Java Application
# Photo Album Java Application
photoalbum-java-app:
build:
context: .
dockerfile: Dockerfile
container_name: photoalbum-java-app
environment:
- SPRING_PROFILES_ACTIVE=docker
- SPRING_DATASOURCE_URL=jdbc:oracle:thin:@oracle-db:1521:XE
- SPRING_DATASOURCE_USERNAME=photoalbum
- SPRING_DATASOURCE_PASSWORD=photoalbum
- SPRING_DATASOURCE_URL=jdbc:postgresql://postgres-db:5432/photoalbum
- POSTGRES_USERNAME=photoalbum
- POSTGRES_PASSWORD=photoalbum
ports:
- "8080:8080"
depends_on:
oracle-db:
postgres-db:
condition: service_healthy
networks:
- photoalbum-network
restart: on-failure

volumes:
oracle_data:
postgres_data:

networks:
photoalbum-network:
Expand Down
36 changes: 0 additions & 36 deletions oracle-init/01-create-user.sql

This file was deleted.

14 changes: 0 additions & 14 deletions oracle-init/02-verify-user.sql

This file was deleted.

35 changes: 0 additions & 35 deletions oracle-init/create-user.sh

This file was deleted.

3 changes: 0 additions & 3 deletions oracle-init/healthcheck.sql

This file was deleted.

21 changes: 15 additions & 6 deletions pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

Expand All @@ -18,7 +18,7 @@
<packaging>jar</packaging>

<name>Photo Album</name>
<description>A simple photo storage and gallery application built with Spring Boot and Oracle DB</description>
<description>A simple photo storage and gallery application built with Spring Boot and PostgreSQL</description>

<properties>
<java.version>1.8</java.version>
Expand Down Expand Up @@ -46,10 +46,14 @@
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Oracle JDBC Driver -->
<!-- PostgreSQL JDBC Driver -->
<!-- Migrated from Oracle to PostgreSQL according to Build file check item 1: Replace Oracle JDBC driver with PostgreSQL driver dependency. -->
<!-- CVE Fix: Explicitly set to 42.7.2 to fix CVE-2024-1597 (CRITICAL severity - SQL injection in simple query mode) -->
<!-- Note: Spring Boot 2.7.18 manages PostgreSQL at 42.3.8 which has this CVE, so we override to secure version -->
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.7.2</version>
<scope>runtime</scope>
</dependency>

Expand All @@ -60,10 +64,11 @@
</dependency>

<!-- Commons IO for file operations -->
<!-- CVE Fix: Upgraded from 2.11.0 to 2.14.0 to fix CVE-2024-47554 (HIGH severity - DoS attack on XmlStreamReader) -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
<version>2.14.0</version>
</dependency>

<!-- Image processing -->
Expand All @@ -80,9 +85,13 @@
</dependency>

<!-- H2 Database for testing -->
<!-- CVE Fix: Set to 2.2.224 to fix CVE-2022-45868 and maintain Java 8 compatibility -->
<!-- Note: Spring Boot 2.7.18 manages H2 at 2.1.214 which has CVE, version 2.3.x requires Java 11+ -->
<!-- Version 2.2.224 is CVE-free and compatible with Java 8 (class file version 52.0) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<scope>test</scope>
</dependency>

Expand Down
24 changes: 24 additions & 0 deletions postgres-init/01-create-user.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-- Migrated from Oracle to PostgreSQL according to SQL check item 1: Use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE).
-- This script runs automatically when PostgreSQL container starts
-- It creates the photoalbum user and database

-- Create photoalbum user
CREATE USER photoalbum WITH PASSWORD 'photoalbum';

-- Create photoalbum database
CREATE DATABASE photoalbum WITH OWNER photoalbum;

-- Grant privileges to photoalbum user on the database
GRANT ALL PRIVILEGES ON DATABASE photoalbum TO photoalbum;

-- Connect to photoalbum database
\c photoalbum

-- Grant schema privileges
GRANT ALL ON SCHEMA public TO photoalbum;
GRANT CREATE ON SCHEMA public TO photoalbum;

-- Grant default privileges for future objects
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO photoalbum;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO photoalbum;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON FUNCTIONS TO photoalbum;
13 changes: 13 additions & 0 deletions postgres-init/02-verify-user.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- Migrated from Oracle to PostgreSQL according to SQL check item 1: Use lowercase for identifiers (like table and column names) and data type (like varchar), use uppercase for SQL keywords (like SELECT, FROM, WHERE).
-- Verify photoalbum user exists and can access the database

-- Connect to photoalbum database
\c photoalbum photoalbum

-- Verify user can query
SELECT current_user, current_database();

-- List available tables (will be empty initially)
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public';
3 changes: 3 additions & 0 deletions postgres-init/healthcheck.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- Migrated from Oracle to PostgreSQL according to SQL check item 3: Remove FROM DUAL in SELECT statements that only return values.
-- Health check script for PostgreSQL DB
SELECT 1;
16 changes: 8 additions & 8 deletions src/main/java/com/photoalbum/controller/PhotoFileController.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import java.util.Optional;

/**
* Controller for serving photo files from Oracle database BLOB storage
* Controller for serving photo files from PostgreSQL database BLOB storage
*/
@Controller
@RequestMapping("/photo")
Expand All @@ -32,7 +32,7 @@ public PhotoFileController(PhotoService photoService) {
}

/**
* Serves a photo file by ID from Oracle database BLOB storage
* Serves a photo file by ID from PostgreSQL database BLOB storage
*/
@GetMapping("/{id}")
public ResponseEntity<Resource> servePhoto(@PathVariable String id) {
Expand All @@ -51,24 +51,24 @@ public ResponseEntity<Resource> servePhoto(@PathVariable String id) {
}

Photo photo = photoOpt.get();
logger.info("Found photo: originalFileName={}, mimeType={}",
logger.info("Found photo: originalFileName={}, mimeType={}",
photo.getOriginalFileName(), photo.getMimeType());

// Get photo data from Oracle database BLOB
// Get photo data from PostgreSQL database BLOB
byte[] photoData = photo.getPhotoData();
if (photoData == null || photoData.length == 0) {
logger.error("No photo data found for photo ID {}", id);
return ResponseEntity.notFound().build();
}

logger.info("Photo data retrieved: {} bytes, first 10 bytes: {}",
photoData.length,
logger.info("Photo data retrieved: {} bytes, first 10 bytes: {}",
photoData.length,
photoData.length >= 10 ? java.util.Arrays.toString(java.util.Arrays.copyOf(photoData, 10)) : "less than 10 bytes");

// Create resource from byte array
Resource resource = new ByteArrayResource(photoData);

logger.info("Serving photo ID {} ({}, {} bytes) from Oracle database",
logger.info("Serving photo ID {} ({}, {} bytes) from PostgreSQL database",
id, photo.getOriginalFileName(), photoData.length);

// Return the photo data with appropriate content type and aggressive no-cache headers
Expand All @@ -82,7 +82,7 @@ public ResponseEntity<Resource> servePhoto(@PathVariable String id) {
.header("X-Photo-Size", String.valueOf(photoData.length))
.body(resource);
} catch (Exception ex) {
logger.error("Error serving photo with ID {} from Oracle database", id, ex);
logger.error("Error serving photo with ID {} from PostgreSQL database", id, ex);
return ResponseEntity.status(500).build();
}
}
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/com/photoalbum/model/Photo.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ public class Photo {
private String originalFileName;

/**
* Binary photo data stored directly in Oracle database
* Binary photo data stored directly in PostgreSQL database
* Migrated from Oracle to PostgreSQL according to java check item 1: Convert all table and column names from uppercase to lowercase in JPA annotations.
*/
@Lob
@Column(name = "photo_data", nullable = true)
Expand All @@ -57,10 +58,11 @@ public class Photo {

/**
* File size in bytes
* Migrated from Oracle to PostgreSQL according to java check item 1: Convert all table and column names from uppercase to lowercase in JPA annotations.
*/
@NotNull
@Positive
@Column(name = "file_size", nullable = false, columnDefinition = "NUMBER(19,0)")
@Column(name = "file_size", nullable = false)
private Long fileSize;

/**
Expand All @@ -73,9 +75,10 @@ public class Photo {

/**
* Timestamp of upload
* Migrated from Oracle to PostgreSQL according to java check item 1: Convert all table and column names from uppercase to lowercase in JPA annotations.
*/
@NotNull
@Column(name = "uploaded_at", nullable = false, columnDefinition = "TIMESTAMP DEFAULT SYSTIMESTAMP")
@Column(name = "uploaded_at", nullable = false)
private LocalDateTime uploadedAt;

/**
Expand Down
Loading