feat: add jakarta rest todo implementation with devcontainer setup
This commit is contained in:
parent
b75d5b2d11
commit
d605c3bd7d
24 changed files with 1286 additions and 0 deletions
|
|
@ -0,0 +1,8 @@
|
|||
.git
|
||||
.github
|
||||
.settings
|
||||
target
|
||||
*.iml
|
||||
.idea
|
||||
.vscode
|
||||
node_modules
|
||||
27
cmd/jws/projects/jakarta-rest-todo/.devcontainer/.gitignore
vendored
Normal file
27
cmd/jws/projects/jakarta-rest-todo/.devcontainer/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# Maven
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
# IDE-spezifische Dateien
|
||||
.idea/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
.vscode/
|
||||
.settings/
|
||||
.classpath
|
||||
.project
|
||||
.factorypath
|
||||
|
||||
# Temporäre Dateien
|
||||
*.log
|
||||
*.tmp
|
||||
*.temp
|
||||
|
||||
# Lokale Konfigurationsdateien
|
||||
src/main/resources/application-local.properties
|
||||
|
||||
# Devcontainer Volumen
|
||||
.devcontainer/postgres-data/
|
||||
12
cmd/jws/projects/jakarta-rest-todo/.devcontainer/Dockerfile
Normal file
12
cmd/jws/projects/jakarta-rest-todo/.devcontainer/Dockerfile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
FROM icr.io/appcafe/open-liberty:23.0.0.4-kernel-slim-java17-openj9-ubi
|
||||
|
||||
COPY --chown=1001:0 src/main/liberty/config /config
|
||||
# # Verzeichnis erstellen und PostgreSQL JDBC-Treiber herunterladen
|
||||
RUN mkdir -p /config/lib && \
|
||||
curl -o /config/lib/postgresql.jar https://jdbc.postgresql.org/download/postgresql-42.6.0.jar
|
||||
|
||||
RUN features.sh
|
||||
|
||||
#COPY --chown=1001:0 target/*.war /config/apps
|
||||
|
||||
RUN configure.sh
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
FROM mcr.microsoft.com/devcontainers/java:1-21-bullseye
|
||||
|
||||
#ARG INSTALL_MAVEN="true"
|
||||
#ARG MAVEN_VERSION=""
|
||||
|
||||
#ARG INSTALL_GRADLE="false"
|
||||
#ARG GRADLE_VERSION=""
|
||||
|
||||
#RUN if [ "${INSTALL_MAVEN}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install maven \"${MAVEN_VERSION}\""; fi \
|
||||
# && if [ "${INSTALL_GRADLE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/sdkman/bin/sdkman-init.sh && sdk install gradle \"${GRADLE_VERSION}\""; fi
|
||||
|
||||
# Hier kannst du zusätzliche Tools oder Bibliotheken installieren, die du für die Entwicklung benötigst.
|
||||
# Zum Beispiel den PostgreSQL JDBC-Treiber, wenn du ihn für die Entwicklung benötigst:
|
||||
RUN apt-get update && apt-get install -y curl && curl -o /tmp/postgresql.jar https://jdbc.postgresql.org/download/postgresql-42.6.0.jar && mkdir -p /usr/local/lib/ && mv /tmp/postgresql.jar /usr/local/lib/postgresql.jar
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "Java & PostgreSQL",
|
||||
"dockerComposeFile": "docker-compose.yml",
|
||||
"service": "app",
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
"forwardPorts": [9080, 5432, 9433],
|
||||
"postCreateCommand": "mvn clean install -DskipTests",
|
||||
"remoteUser": "vscode",
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/docker-in-docker:2": {"version": "latest"},
|
||||
"ghcr.io/devcontainers-extra/features/maven-sdkman:2": {"version": "latest"},
|
||||
"ghcr.io/devcontainers/features/git:1": {"version": "latest"}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
services:
|
||||
app:
|
||||
container_name: javadev
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: .devcontainer/Dockerfile.dev
|
||||
volumes:
|
||||
- ../..:/workspaces:cached
|
||||
- ./app:/app
|
||||
environment:
|
||||
POSTGRES_HOST: postgresdb
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_DB: postgres
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
networks:
|
||||
- my_network
|
||||
command: sleep infinity
|
||||
|
||||
openliberty:
|
||||
container_name: openliberty_app
|
||||
build:
|
||||
context: ../
|
||||
dockerfile: .devcontainer/Dockerfile
|
||||
ports:
|
||||
- "9080:9080"
|
||||
- "9443:9443"
|
||||
environment:
|
||||
POSTGRES_HOST: postgresdb
|
||||
POSTGRES_PORT: 5432
|
||||
POSTGRES_DB: todo_db
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
volumes:
|
||||
- ./app:/config/dropins
|
||||
depends_on:
|
||||
- db
|
||||
networks:
|
||||
- my_network
|
||||
|
||||
db:
|
||||
container_name: postgresdb
|
||||
image: postgres:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_DB: todo_db
|
||||
networks:
|
||||
- my_network
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
|
||||
networks:
|
||||
my_network:
|
||||
driver: bridge
|
||||
19
cmd/jws/projects/jakarta-rest-todo/.devcontainer/init.sql
Normal file
19
cmd/jws/projects/jakarta-rest-todo/.devcontainer/init.sql
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
CREATE TABLE users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username VARCHAR(255) NOT NULL UNIQUE,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE todos (
|
||||
id SERIAL PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description VARCHAR(1000),
|
||||
target_date DATE,
|
||||
completed BOOLEAN,
|
||||
user_id BIGINT NOT NULL,
|
||||
FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
INSERT INTO users (username, password, email) VALUES
|
||||
('test', '$2a$12$nt7xQKNDKZhxQFZGD5Wy0.Uh0wdPtWDgwfnWnPLgBWnQDGGkNLKBi', 'test@example.com');
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.todoapp</groupId>
|
||||
<artifactId>todo-app</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<jakartaee.version>10.0.0</jakartaee.version>
|
||||
<hibernate.version>6.2.5.Final</hibernate.version>
|
||||
<postgresql.version>42.6.0</postgresql.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- Jakarta EE 10 API -->
|
||||
<dependency>
|
||||
<groupId>jakarta.platform</groupId>
|
||||
<artifactId>jakarta.jakartaee-api</artifactId>
|
||||
<version>${jakartaee.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Hibernate Core -->
|
||||
<dependency>
|
||||
<groupId>org.hibernate.orm</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>${hibernate.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- PostgreSQL JDBC Driver -->
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<version>${postgresql.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JSTL -->
|
||||
<dependency>
|
||||
<groupId>jakarta.servlet.jsp.jstl</groupId>
|
||||
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish.web</groupId>
|
||||
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
|
||||
<version>3.0.1</version>
|
||||
</dependency>
|
||||
|
||||
<!-- JAX-RS -->
|
||||
<dependency>
|
||||
<groupId>jakarta.ws.rs</groupId>
|
||||
<artifactId>jakarta.ws.rs-api</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON-Binding -->
|
||||
<dependency>
|
||||
<groupId>jakarta.json.bind</groupId>
|
||||
<artifactId>jakarta.json.bind-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- JSON-Processing -->
|
||||
<dependency>
|
||||
<groupId>jakarta.json</groupId>
|
||||
<artifactId>jakarta.json-api</artifactId>
|
||||
<version>2.1.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hibernate</groupId>
|
||||
<artifactId>hibernate-core</artifactId>
|
||||
<version>6.3.1.Final</version> <!-- Stelle sicher, dass du eine aktuelle Version benutzt -->
|
||||
</dependency>
|
||||
<!-- Mindestens zum Passwort-Hashing -->
|
||||
<dependency>
|
||||
<groupId>at.favre.lib</groupId>
|
||||
<artifactId>bcrypt</artifactId>
|
||||
<version>0.10.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>todo-app</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
<version>3.3.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>io.openliberty.tools</groupId>
|
||||
<artifactId>liberty-maven-plugin</artifactId>
|
||||
<version>3.7.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
package com.todoapp.dao;
|
||||
|
||||
import com.todoapp.model.Todo;
|
||||
import com.todoapp.model.User;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.query.Query;
|
||||
import java.util.List;
|
||||
|
||||
@ApplicationScoped
|
||||
public class TodoDAO {
|
||||
|
||||
@Inject
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
@Inject
|
||||
private UserDAO userDAO;
|
||||
|
||||
public Todo saveTodo(Todo todo, String username) {
|
||||
Transaction transaction = null;
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
transaction = session.beginTransaction();
|
||||
|
||||
// Benutzer aus der Datenbank holen
|
||||
User user = userDAO.getUserByUsername(username);
|
||||
if (user == null) {
|
||||
throw new IllegalArgumentException("User not found");
|
||||
}
|
||||
|
||||
todo.setUser(user);
|
||||
session.persist(todo);
|
||||
transaction.commit();
|
||||
return todo;
|
||||
} catch (Exception e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error saving todo", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Todo updateTodo(Todo todo) {
|
||||
Transaction transaction = null;
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
transaction = session.beginTransaction();
|
||||
Todo updatedTodo = session.merge(todo);
|
||||
transaction.commit();
|
||||
return updatedTodo;
|
||||
} catch (Exception e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error updating todo", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteTodo(Long id) {
|
||||
Transaction transaction = null;
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
transaction = session.beginTransaction();
|
||||
Todo todo = session.get(Todo.class, id);
|
||||
if (todo != null) {
|
||||
session.remove(todo);
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error deleting todo", e);
|
||||
}
|
||||
}
|
||||
|
||||
public Todo getTodoById(Long id) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
return session.get(Todo.class, id);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting todo by ID", e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Todo> getAllTodos() {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
return session.createQuery("FROM Todo", Todo.class).list();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting all todos", e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Todo> getTodosByUsername(String username) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
Query<Todo> query = session.createQuery(
|
||||
"FROM Todo t WHERE t.user.username = :username ORDER BY t.completed, t.targetDate", Todo.class);
|
||||
query.setParameter("username", username);
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting todos by username", e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Todo> getCompletedTodosByUsername(String username) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
Query<Todo> query = session.createQuery(
|
||||
"FROM Todo t WHERE t.user.username = :username AND t.completed = true", Todo.class);
|
||||
query.setParameter("username", username);
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting completed todos", e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Todo> getIncompleteTodosByUsername(String username) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
Query<Todo> query = session.createQuery(
|
||||
"FROM Todo t WHERE t.user.username = :username AND t.completed = false ORDER BY t.targetDate", Todo.class);
|
||||
query.setParameter("username", username);
|
||||
return query.list();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting incomplete todos", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
package com.todoapp.dao;
|
||||
|
||||
import com.todoapp.model.User;
|
||||
import com.todoapp.util.HibernateUtil;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.Transaction;
|
||||
import org.hibernate.query.Query;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
@ApplicationScoped
|
||||
public class UserDAO {
|
||||
|
||||
@Inject
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
public User saveUser(User user) {
|
||||
Transaction transaction = null;
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
transaction = session.beginTransaction();
|
||||
session.persist(user);
|
||||
transaction.commit();
|
||||
return user;
|
||||
} catch (Exception e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error saving user", e);
|
||||
}
|
||||
}
|
||||
|
||||
public User updateUser(User user) {
|
||||
Transaction transaction = null;
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
transaction = session.beginTransaction();
|
||||
User updatedUser = session.merge(user);
|
||||
transaction.commit();
|
||||
return updatedUser;
|
||||
} catch (Exception e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error updating user", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean deleteUser(Long id) {
|
||||
Transaction transaction = null;
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
transaction = session.beginTransaction();
|
||||
User user = session.get(User.class, id);
|
||||
if (user != null) {
|
||||
session.remove(user);
|
||||
transaction.commit();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
if (transaction != null) {
|
||||
transaction.rollback();
|
||||
}
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error deleting user", e);
|
||||
}
|
||||
}
|
||||
|
||||
public User getUserById(Long id) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
return session.get(User.class, id);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting user by ID", e);
|
||||
}
|
||||
}
|
||||
|
||||
public User getUserByUsername(String username) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
Query<User> query = session.createQuery("FROM User WHERE username = :username", User.class);
|
||||
query.setParameter("username", username);
|
||||
return query.uniqueResult();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting user by username", e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<User> getAllUsers() {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
return session.createQuery("FROM User", User.class).list();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error getting all users", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean usernameExists(String username) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
Query<Long> query = session.createQuery(
|
||||
"SELECT COUNT(u) FROM User u WHERE u.username = :username", Long.class);
|
||||
query.setParameter("username", username);
|
||||
return query.uniqueResult() > 0;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error checking if username exists", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean emailExists(String email) {
|
||||
try (Session session = sessionFactory.openSession()) {
|
||||
Query<Long> query = session.createQuery(
|
||||
"SELECT COUNT(u) FROM User u WHERE u.email = :email", Long.class);
|
||||
query.setParameter("email", email);
|
||||
return query.uniqueResult() > 0;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Error checking if email exists", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.todoapp.dto;
|
||||
|
||||
public class LoginRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
|
||||
// Getter und Setter
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.todoapp.dto;
|
||||
|
||||
public class RegistrationRequest {
|
||||
private String username;
|
||||
private String password;
|
||||
private String email;
|
||||
|
||||
// Getter und Setter
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package com.todoapp.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.json.bind.annotation.JsonbTransient;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "todos")
|
||||
public class Todo implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String title;
|
||||
|
||||
@Column(length = 1000)
|
||||
private String description;
|
||||
|
||||
@Column(name = "target_date")
|
||||
@Temporal(TemporalType.DATE)
|
||||
private Date targetDate;
|
||||
|
||||
@Column
|
||||
private boolean completed;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "user_id", nullable = false)
|
||||
@JsonbTransient // Verhindert zirkuläre Referenzen
|
||||
private User user;
|
||||
|
||||
// Konstruktoren
|
||||
public Todo() {
|
||||
}
|
||||
|
||||
public Todo(String title, String description, Date targetDate, boolean completed) {
|
||||
this.title = title;
|
||||
this.description = description;
|
||||
this.targetDate = targetDate;
|
||||
this.completed = completed;
|
||||
}
|
||||
|
||||
// Getter und Setter
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Date getTargetDate() {
|
||||
return targetDate;
|
||||
}
|
||||
|
||||
public void setTargetDate(Date targetDate) {
|
||||
this.targetDate = targetDate;
|
||||
}
|
||||
|
||||
public boolean isCompleted() {
|
||||
return completed;
|
||||
}
|
||||
|
||||
public void setCompleted(boolean completed) {
|
||||
this.completed = completed;
|
||||
}
|
||||
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void setUser(User user) {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
// Zusätzliche Methode für REST-Antworten
|
||||
public Long getUserId() {
|
||||
return user != null ? user.getId() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Todo{" +
|
||||
"id=" + id +
|
||||
", title='" + title + '\'' +
|
||||
", description='" + description + '\'' +
|
||||
", targetDate=" + targetDate +
|
||||
", completed=" + completed +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
package com.todoapp.model;
|
||||
|
||||
import jakarta.persistence.*;
|
||||
import jakarta.json.bind.annotation.JsonbTransient;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Entity
|
||||
@Table(name = "users")
|
||||
public class User implements Serializable {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
private String username;
|
||||
|
||||
@Column(nullable = false)
|
||||
@JsonbTransient // Verhindert, dass das Passwort in JSON serialisiert wird
|
||||
private String password;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String email;
|
||||
|
||||
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
|
||||
@JsonbTransient // Verhindert zirkuläre Referenzen bei der JSON-Serialisierung
|
||||
private List<Todo> todos = new ArrayList<>();
|
||||
|
||||
// Konstruktoren
|
||||
public User() {
|
||||
}
|
||||
|
||||
public User(String username, String password, String email) {
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
// Getter und Setter
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
public List<Todo> getTodos() {
|
||||
return todos;
|
||||
}
|
||||
|
||||
public void setTodos(List<Todo> todos) {
|
||||
this.todos = todos;
|
||||
}
|
||||
|
||||
// Hilfsmethoden
|
||||
public void addTodo(Todo todo) {
|
||||
todos.add(todo);
|
||||
todo.setUser(this);
|
||||
}
|
||||
|
||||
public void removeTodo(Todo todo) {
|
||||
todos.remove(todo);
|
||||
todo.setUser(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "User{" +
|
||||
"id=" + id +
|
||||
", username='" + username + '\'' +
|
||||
", email='" + email + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
package com.todoapp.rest;
|
||||
|
||||
import com.todoapp.dao.UserDAO;
|
||||
import com.todoapp.model.User;
|
||||
import com.todoapp.dto.LoginRequest;
|
||||
import com.todoapp.dto.RegistrationRequest;
|
||||
|
||||
import jakarta.annotation.security.RolesAllowed;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import java.util.Map;
|
||||
|
||||
@Path("/auth")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class AuthResource {
|
||||
|
||||
@Inject
|
||||
private UserDAO userDAO;
|
||||
|
||||
@POST
|
||||
@Path("/register")
|
||||
public Response register(RegistrationRequest request) {
|
||||
if (request.getUsername() == null || request.getPassword() == null || request.getEmail() == null) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Username, password, and email are required"))
|
||||
.build();
|
||||
}
|
||||
|
||||
if (userDAO.usernameExists(request.getUsername())) {
|
||||
System.out.println(userDAO.usernameExists(request.getUsername()));
|
||||
return Response.status(Response.Status.CONFLICT)
|
||||
.entity(Map.of("error", "Username already exists"))
|
||||
.build();
|
||||
}
|
||||
|
||||
if (userDAO.emailExists(request.getEmail())) {
|
||||
return Response.status(Response.Status.CONFLICT)
|
||||
.entity(Map.of("error", "Email already exists"))
|
||||
.build();
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
user.setUsername(request.getUsername());
|
||||
user.setEmail(request.getEmail());
|
||||
|
||||
String hashedPassword = BCrypt.withDefaults()
|
||||
.hashToString(12, request.getPassword().toCharArray());
|
||||
user.setPassword(hashedPassword);
|
||||
|
||||
userDAO.saveUser(user);
|
||||
|
||||
return Response.status(Response.Status.CREATED)
|
||||
.entity(Map.of("message", "User registered successfully"))
|
||||
.build();
|
||||
}
|
||||
|
||||
@POST
|
||||
@RolesAllowed("user")
|
||||
@Path("/login")
|
||||
public Response login(LoginRequest request) {
|
||||
// Validierung
|
||||
if (request.getUsername() == null || request.getPassword() == null) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(Map.of("error", "Username and password are required"))
|
||||
.build();
|
||||
}
|
||||
|
||||
// Benutzer suchen
|
||||
User user = userDAO.getUserByUsername(request.getUsername());
|
||||
if (user == null) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED)
|
||||
.entity(Map.of("error", "Invalid credentials"))
|
||||
.build();
|
||||
}
|
||||
|
||||
// Passwort überprüfen
|
||||
BCrypt.Result result = BCrypt.verifyer()
|
||||
.verify(request.getPassword().toCharArray(), user.getPassword());
|
||||
if (!result.verified) {
|
||||
return Response.status(Response.Status.UNAUTHORIZED)
|
||||
.entity(Map.of("error", "Invalid credentials"))
|
||||
.build();
|
||||
}
|
||||
|
||||
// Erfolgreiche Anmeldung
|
||||
return Response.ok(Map.of(
|
||||
"message", "Login successful",
|
||||
"username", user.getUsername(),
|
||||
"email", user.getEmail())).build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package com.todoapp.rest;
|
||||
|
||||
import jakarta.ws.rs.ApplicationPath;
|
||||
import jakarta.ws.rs.core.Application;
|
||||
|
||||
@ApplicationPath("/api")
|
||||
public class TodoApplication extends Application {
|
||||
// Die leere Klasse ist ausreichend, um den REST-Endpunkt zu definieren
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package com.todoapp.rest;
|
||||
|
||||
import com.todoapp.dao.TodoDAO;
|
||||
import com.todoapp.model.Todo;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.*;
|
||||
import jakarta.ws.rs.core.Context;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
import java.util.List;
|
||||
|
||||
@Path("/todos")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public class TodoResource {
|
||||
|
||||
@Inject
|
||||
private TodoDAO todoDAO;
|
||||
|
||||
@GET
|
||||
public Response getAllTodos(@Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
List<Todo> todos = todoDAO.getTodosByUsername(username);
|
||||
return Response.ok(todos).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
public Response getTodoById(@PathParam("id") Long id, @Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
Todo todo = todoDAO.getTodoById(id);
|
||||
|
||||
if (todo == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
// Sicherheitscheck: Nutzer darf nur eigene Todos sehen
|
||||
if (!todo.getUser().getUsername().equals(username)) {
|
||||
return Response.status(Response.Status.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
return Response.ok(todo).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/completed")
|
||||
public Response getCompletedTodos(@Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
List<Todo> todos = todoDAO.getCompletedTodosByUsername(username);
|
||||
return Response.ok(todos).build();
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/incomplete")
|
||||
public Response getIncompleteTodos(@Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
List<Todo> todos = todoDAO.getIncompleteTodosByUsername(username);
|
||||
return Response.ok(todos).build();
|
||||
}
|
||||
|
||||
@POST
|
||||
public Response createTodo(Todo todo, @Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
todo = todoDAO.saveTodo(todo, username);
|
||||
return Response.status(Response.Status.CREATED).entity(todo).build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}")
|
||||
public Response updateTodo(@PathParam("id") Long id, Todo updatedTodo, @Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
Todo existingTodo = todoDAO.getTodoById(id);
|
||||
|
||||
if (existingTodo == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
// Sicherheitscheck: Nutzer darf nur eigene Todos aktualisieren
|
||||
if (!existingTodo.getUser().getUsername().equals(username)) {
|
||||
return Response.status(Response.Status.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
// ID und Benutzer beibehalten
|
||||
updatedTodo.setId(id);
|
||||
updatedTodo.setUser(existingTodo.getUser());
|
||||
|
||||
todoDAO.updateTodo(updatedTodo);
|
||||
return Response.ok(updatedTodo).build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/{id}")
|
||||
public Response deleteTodo(@PathParam("id") Long id, @Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
Todo todo = todoDAO.getTodoById(id);
|
||||
|
||||
if (todo == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
// Sicherheitscheck: Nutzer darf nur eigene Todos löschen
|
||||
if (!todo.getUser().getUsername().equals(username)) {
|
||||
return Response.status(Response.Status.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
boolean deleted = todoDAO.deleteTodo(id);
|
||||
return deleted ? Response.noContent().build() : Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/{id}/complete")
|
||||
public Response markTodoComplete(@PathParam("id") Long id, @Context SecurityContext securityContext) {
|
||||
String username = securityContext.getUserPrincipal().getName();
|
||||
Todo todo = todoDAO.getTodoById(id);
|
||||
|
||||
if (todo == null) {
|
||||
return Response.status(Response.Status.NOT_FOUND).build();
|
||||
}
|
||||
|
||||
// Sicherheitscheck: Nutzer darf nur eigene Todos aktualisieren
|
||||
if (!todo.getUser().getUsername().equals(username)) {
|
||||
return Response.status(Response.Status.FORBIDDEN).build();
|
||||
}
|
||||
|
||||
todo.setCompleted(true);
|
||||
todoDAO.updateTodo(todo);
|
||||
return Response.ok(todo).build();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
package com.todoapp.security;
|
||||
|
||||
import com.todoapp.dao.UserDAO;
|
||||
import com.todoapp.model.User;
|
||||
import jakarta.annotation.Priority;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.Priorities;
|
||||
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||
import jakarta.ws.rs.container.ContainerRequestFilter;
|
||||
import jakarta.ws.rs.core.HttpHeaders;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import jakarta.ws.rs.core.SecurityContext;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.util.Base64;
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
|
||||
@Provider
|
||||
@Priority(Priorities.AUTHENTICATION)
|
||||
@ApplicationScoped
|
||||
public class BasicAuthenticationFilter implements ContainerRequestFilter {
|
||||
|
||||
@Inject
|
||||
private UserDAO userDAO;
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext) throws IOException {
|
||||
System.out.println("BasicAuthenticationFilter triggered for path: " + requestContext.getUriInfo().getPath());
|
||||
String path = requestContext.getUriInfo().getPath();
|
||||
if (path.endsWith("auth/register") || path.endsWith("auth/login")) {
|
||||
return;
|
||||
}
|
||||
|
||||
String authHeader = requestContext.getHeaderString(HttpHeaders.AUTHORIZATION);
|
||||
if (authHeader == null || !authHeader.startsWith("Basic ")) {
|
||||
abortWithUnauthorized(requestContext);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] credentials = extractCredentials(authHeader);
|
||||
if (credentials.length != 2) {
|
||||
abortWithUnauthorized(requestContext);
|
||||
return;
|
||||
}
|
||||
|
||||
String username = credentials[0];
|
||||
String password = credentials[1];
|
||||
|
||||
User user = userDAO.getUserByUsername(username);
|
||||
if (user == null) {
|
||||
abortWithUnauthorized(requestContext);
|
||||
return;
|
||||
}
|
||||
|
||||
BCrypt.Result result = BCrypt.verifyer()
|
||||
.verify(password.toCharArray(), user.getPassword());
|
||||
if (!result.verified) {
|
||||
abortWithUnauthorized(requestContext);
|
||||
return;
|
||||
}
|
||||
|
||||
final SecurityContext currentSecurityContext = requestContext.getSecurityContext();
|
||||
requestContext.setSecurityContext(new SecurityContext() {
|
||||
@Override
|
||||
public Principal getUserPrincipal() {
|
||||
return () -> username;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUserInRole(String role) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return currentSecurityContext.isSecure();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthenticationScheme() {
|
||||
return "BASIC";
|
||||
}
|
||||
});
|
||||
System.out.println("SecurityContext gesetzt für User: " + username);
|
||||
System.out.println("User in Rolle user: " + requestContext.getSecurityContext().isUserInRole("user"));
|
||||
|
||||
}
|
||||
|
||||
private String[] extractCredentials(String authHeader) {
|
||||
String base64Credentials = authHeader.substring("Basic ".length()).trim();
|
||||
byte[] decoded = Base64.getDecoder().decode(base64Credentials);
|
||||
String credentials = new String(decoded);
|
||||
return credentials.split(":", 2);
|
||||
}
|
||||
|
||||
private void abortWithUnauthorized(ContainerRequestContext requestContext) {
|
||||
requestContext.abortWith(Response
|
||||
.status(Response.Status.UNAUTHORIZED)
|
||||
.header(HttpHeaders.WWW_AUTHENTICATE, "Basic realm=\"TodoApp\"")
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.todoapp.security;
|
||||
|
||||
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||
import jakarta.ws.rs.container.ContainerResponseContext;
|
||||
import jakarta.ws.rs.container.ContainerResponseFilter;
|
||||
import jakarta.ws.rs.ext.Provider;
|
||||
import java.io.IOException;
|
||||
|
||||
@Provider
|
||||
public class CORSFilter implements ContainerResponseFilter {
|
||||
|
||||
@Override
|
||||
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
|
||||
throws IOException {
|
||||
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
|
||||
responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
||||
responseContext.getHeaders().add("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
||||
responseContext.getHeaders().add("Access-Control-Max-Age", "86400");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
package com.todoapp.util;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.enterprise.inject.Produces;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.cfg.Configuration;
|
||||
|
||||
@ApplicationScoped
|
||||
public class HibernateUtil {
|
||||
|
||||
private static SessionFactory sessionFactory;
|
||||
|
||||
@Produces
|
||||
@ApplicationScoped
|
||||
public SessionFactory getSessionFactory() {
|
||||
if (sessionFactory == null) {
|
||||
try {
|
||||
Configuration configuration = new Configuration();
|
||||
configuration.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
|
||||
configuration.setProperty("hibernate.connection.url", "jdbc:postgresql://postgresdb:5432/todo_db");
|
||||
configuration.setProperty("hibernate.connection.username", "postgres");
|
||||
configuration.setProperty("hibernate.connection.password", "postgres");
|
||||
|
||||
// Entity-Klassen registrieren
|
||||
configuration.addAnnotatedClass(com.todoapp.model.User.class);
|
||||
configuration.addAnnotatedClass(com.todoapp.model.Todo.class);
|
||||
|
||||
sessionFactory = configuration.buildSessionFactory();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return sessionFactory;
|
||||
}
|
||||
|
||||
public static void shutdown() {
|
||||
if (sessionFactory != null) {
|
||||
sessionFactory.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<server description="OpenLiberty Todo App Server">
|
||||
|
||||
<featureManager>
|
||||
<feature>servlet-6.0</feature>
|
||||
<feature>pages-3.1</feature>
|
||||
<feature>jdbc-4.2</feature>
|
||||
<feature>jndi-1.0</feature>
|
||||
<feature>monitor-1.0</feature>
|
||||
<feature>restfulWS-3.1</feature>
|
||||
<feature>jsonb-3.0</feature>
|
||||
<feature>jsonp-2.1</feature>
|
||||
<!-- <feature>appSecurity-5.0</feature> -->
|
||||
<feature>transportSecurity-1.0</feature>
|
||||
</featureManager>
|
||||
|
||||
<httpEndpoint id="defaultHttpEndpoint"
|
||||
httpPort="9080"
|
||||
httpsPort="9443" />
|
||||
|
||||
<applicationManager autoExpand="true" />
|
||||
|
||||
<dataSource id="PostgresDataSource" jndiName="jdbc/PostgresDataSource">
|
||||
<jdbcDriver libraryRef="PostgresLib" />
|
||||
<properties.postgresql serverName="${POSTGRES_HOST}"
|
||||
portNumber="${POSTGRES_PORT}"
|
||||
databaseName="${POSTGRES_DB}"
|
||||
user="${POSTGRES_USER}"
|
||||
password="${POSTGRES_PASSWORD}" />
|
||||
</dataSource>
|
||||
|
||||
|
||||
<library id="PostgresLib">
|
||||
<fileset dir="${server.config.dir}/lib" includes="postgresql-*.jar" />
|
||||
</library>
|
||||
|
||||
<webApplication location="todo-app.war" contextRoot="/todo-app" />
|
||||
|
||||
</server>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<persistence xmlns="https://jakarta.ee/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd"
|
||||
version="3.0">
|
||||
<persistence-unit name="todoPU" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
<class>com.todoapp.model.User</class>
|
||||
<class>com.todoapp.model.Todo</class>
|
||||
<properties>
|
||||
<property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/>
|
||||
<property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://postgresdb:5432/todo_db"/>
|
||||
<property name="jakarta.persistence.jdbc.user" value="postgres"/>
|
||||
<property name="jakarta.persistence.jdbc.password" value="postgres"/>
|
||||
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>
|
||||
<property name="hibernate.hbm2ddl.auto" value="update"/>
|
||||
<property name="hibernate.show_sql" value="true"/>
|
||||
</properties>
|
||||
</persistence-unit>
|
||||
</persistence>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE hibernate-configuration PUBLIC
|
||||
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
|
||||
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
|
||||
<hibernate-configuration>
|
||||
<session-factory>
|
||||
<!-- JNDI connection settings -->
|
||||
<property name="hibernate.connection.datasource">jdbc/PostgresDataSource</property>
|
||||
|
||||
<!-- Select our SQL dialect -->
|
||||
<property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>
|
||||
|
||||
<!-- Echo the SQL to stdout -->
|
||||
<property name="hibernate.show_sql">true</property>
|
||||
|
||||
<!-- Set the current session context -->
|
||||
<property name="hibernate.current_session_context_class">thread</property>
|
||||
|
||||
<!-- Drop and re-create the database schema on startup -->
|
||||
<property name="hibernate.hbm2ddl.auto">update</property>
|
||||
|
||||
<!-- Entity mapping -->
|
||||
<mapping class="com.todoapp.model.User"/>
|
||||
<mapping class="com.todoapp.model.Todo"/>
|
||||
</session-factory>
|
||||
</hibernate-configuration>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_0.xsd"
|
||||
version="6.0">
|
||||
|
||||
<display-name>Todo Application</display-name>
|
||||
|
||||
<session-config>
|
||||
<session-timeout>30</session-timeout>
|
||||
</session-config>
|
||||
</web-app>
|
||||
Loading…
Add table
Add a link
Reference in a new issue