dockerfile, other bs
This commit is contained in:
15
Dockerfile
Normal file
15
Dockerfile
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
FROM maven:3.9.9-amazoncorretto-23 AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY . /app
|
||||||
|
|
||||||
|
RUN mvn clean package -DskipTests
|
||||||
|
|
||||||
|
FROM openjdk:23-jdk
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY --from=builder /app/target/wirestream-1.0.0.jar wirestream-1.0.0.jar
|
||||||
|
|
||||||
|
ENTRYPOINT ["java", "-jar", "wirestream-1.0.0.jar"]
|
||||||
30
docker-compose.yml
Normal file
30
docker-compose.yml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
database:
|
||||||
|
image: postgres:latest
|
||||||
|
container_name: accounting-db
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: user
|
||||||
|
POSTGRES_PASSWORD: password
|
||||||
|
POSTGRES_DB: accounting
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
container_name: java-app
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
- "8081:8081"
|
||||||
|
depends_on:
|
||||||
|
- database
|
||||||
|
networks:
|
||||||
|
- app-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app-network:
|
||||||
|
driver: bridge
|
||||||
16
pom.xml
16
pom.xml
@@ -88,13 +88,15 @@
|
|||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-jar-plugin</artifactId>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
<version>3.2.0</version>
|
<version>3.2.0</version>
|
||||||
<executions>
|
<configuration>
|
||||||
<execution>
|
<archive>
|
||||||
<goals>
|
<manifest>
|
||||||
<goal>test-jar</goal>
|
<addClasspath>true</addClasspath>
|
||||||
</goals>
|
<classpathPrefix>lib/</classpathPrefix>
|
||||||
</execution>
|
<mainClass>io.github.lumijiez.example.Main</mainClass>
|
||||||
</executions>
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
<plugin>
|
<plugin>
|
||||||
|
|||||||
2
resources/test.txt
Normal file
2
resources/test.txt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
hellp
|
||||||
|
hellp
|
||||||
@@ -13,10 +13,12 @@ import io.github.lumijiez.example.models.Product;
|
|||||||
import io.github.lumijiez.core.logging.Logger;
|
import io.github.lumijiez.core.logging.Logger;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
ThreadedWriter writer = new ThreadedWriter("test.txt");
|
||||||
ProductDao productDao = new ProductDao();
|
ProductDao productDao = new ProductDao();
|
||||||
|
|
||||||
ServerConfig config = new ServerConfig.Builder()
|
ServerConfig config = new ServerConfig.Builder()
|
||||||
@@ -31,6 +33,12 @@ public class Main {
|
|||||||
chain.next(req, res);
|
chain.next(req, res);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.POST("/write/:text", (req, res) -> {
|
||||||
|
Logger.info("PATH", req.getPathParam("text"));
|
||||||
|
writer.writeToFile(req.getPathParam("text"));
|
||||||
|
res.sendResponse(HttpStatus.OK, "OK");
|
||||||
|
});
|
||||||
|
|
||||||
server.GET("/test/:lel/", (req, res) -> {
|
server.GET("/test/:lel/", (req, res) -> {
|
||||||
Logger.info("PATH", req.getPathParam("lel"));
|
Logger.info("PATH", req.getPathParam("lel"));
|
||||||
Logger.info("QUERY", req.getQueryParam("lol"));
|
Logger.info("QUERY", req.getQueryParam("lol"));
|
||||||
@@ -78,9 +86,10 @@ public class Main {
|
|||||||
res.sendJson(HttpStatus.OK, product);
|
res.sendJson(HttpStatus.OK, product);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.GET("/products", (req, res) -> {
|
server.GET("/products/:page/", (req, res) -> {
|
||||||
Product product = productDao.getProductById(5);
|
Logger.info("PATH", req.getPathParam("page"));
|
||||||
res.sendResponse(HttpStatus.OK, product.toString());
|
List<Product> products = productDao.getProductsByPage(Integer.parseInt(req.getPathParam("page")), 5);
|
||||||
|
res.sendResponse(HttpStatus.OK, products.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
WebSocketServer wsServer = new WebSocketServer(8081);
|
WebSocketServer wsServer = new WebSocketServer(8081);
|
||||||
|
|||||||
50
src/main/java/io/github/lumijiez/example/ThreadedWriter.java
Normal file
50
src/main/java/io/github/lumijiez/example/ThreadedWriter.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package io.github.lumijiez.example;
|
||||||
|
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.concurrent.locks.Lock;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
|
public class ThreadedWriter {
|
||||||
|
private final String filePath;
|
||||||
|
private final Lock lock;
|
||||||
|
|
||||||
|
public ThreadedWriter(String fileName) {
|
||||||
|
String resourcesPath = System.getProperty("user.dir") + "/resources";
|
||||||
|
File resourcesDir = new File(resourcesPath);
|
||||||
|
if (!resourcesDir.exists()) {
|
||||||
|
resourcesDir.mkdirs();
|
||||||
|
}
|
||||||
|
this.filePath = resourcesPath + "/" + fileName;
|
||||||
|
this.lock = new ReentrantLock();
|
||||||
|
createFileIfNotExist();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createFileIfNotExist() {
|
||||||
|
File file = new File(filePath);
|
||||||
|
if (!file.exists()) {
|
||||||
|
try {
|
||||||
|
Files.createDirectories(Paths.get(file.getParent()));
|
||||||
|
file.createNewFile();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Failed to create file: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeToFile(String content) {
|
||||||
|
lock.lock();
|
||||||
|
try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
|
||||||
|
writer.write(content);
|
||||||
|
writer.newLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.err.println("Error writing to file: " + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
lock.unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import io.github.lumijiez.example.models.Product;
|
|||||||
import org.hibernate.Session;
|
import org.hibernate.Session;
|
||||||
import org.hibernate.Transaction;
|
import org.hibernate.Transaction;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.query.Query;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -58,7 +59,6 @@ public class ProductDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void deleteProduct(int id) {
|
public void deleteProduct(int id) {
|
||||||
Transaction transaction = null;
|
Transaction transaction = null;
|
||||||
try (Session session = new Configuration().configure().buildSessionFactory().openSession()) {
|
try (Session session = new Configuration().configure().buildSessionFactory().openSession()) {
|
||||||
@@ -76,4 +76,18 @@ public class ProductDao {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Product> getProductsByPage(int pageNumber, int pageSize) {
|
||||||
|
try (Session session = new Configuration().configure().buildSessionFactory().openSession()) {
|
||||||
|
Query<Product> query = session.createQuery("from Product", Product.class);
|
||||||
|
|
||||||
|
query.setFirstResult((pageNumber - 1) * pageSize);
|
||||||
|
query.setMaxResults(pageSize);
|
||||||
|
|
||||||
|
return query.getResultList();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
<session-factory>
|
<session-factory>
|
||||||
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
|
<property name="hibernate.connection.driver_class">org.postgresql.Driver</property>
|
||||||
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/accounting</property>
|
<property name="hibernate.connection.url">jdbc:postgresql://localhost:5432/accounting</property>
|
||||||
<property name="hibernate.connection.username">postgres</property>
|
<property name="hibernate.connection.username">user</property>
|
||||||
<property name="hibernate.connection.password">postgres</property>
|
<property name="hibernate.connection.password">password</property>
|
||||||
|
|
||||||
<property name="hibernate.c3p0.min_size">5</property>
|
<property name="hibernate.c3p0.min_size">5</property>
|
||||||
<property name="hibernate.c3p0.max_size">20</property>
|
<property name="hibernate.c3p0.max_size">20</property>
|
||||||
|
|||||||
224
uploads/index.html
Normal file
224
uploads/index.html
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>WebSocket Chat</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 20px auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chat-container {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#messages {
|
||||||
|
height: 400px;
|
||||||
|
overflow-y: auto;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
margin: 5px 0;
|
||||||
|
padding: 5px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.sent {
|
||||||
|
background-color: #e3f2fd;
|
||||||
|
margin-left: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.received {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
margin-right: 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#message-input {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
padding: 8px 16px;
|
||||||
|
background-color: #2196f3;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #1976d2;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
background-color: #ccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
#connection-status {
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.connected {
|
||||||
|
background-color: #c8e6c9;
|
||||||
|
color: #2e7d32;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disconnected {
|
||||||
|
background-color: #ffcdd2;
|
||||||
|
color: #c62828;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="chat-container">
|
||||||
|
<h2>WebSocket Chat</h2>
|
||||||
|
<div id="connection-status" class="disconnected">Disconnected</div>
|
||||||
|
<div id="messages"></div>
|
||||||
|
<div class="input-container">
|
||||||
|
<input type="text" id="message-input" placeholder="Type a message..." disabled>
|
||||||
|
<button id="send-btn" disabled>Send</button>
|
||||||
|
<button id="connect-btn">Connect</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const messagesDiv = document.getElementById('messages');
|
||||||
|
const messageInput = document.getElementById('message-input');
|
||||||
|
const sendButton = document.getElementById('send-btn');
|
||||||
|
const connectButton = document.getElementById('connect-btn');
|
||||||
|
const statusDiv = document.getElementById('connection-status');
|
||||||
|
|
||||||
|
let ws = null;
|
||||||
|
let username = null;
|
||||||
|
|
||||||
|
function connect() {
|
||||||
|
if (ws) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get username if not already set
|
||||||
|
if (!username) {
|
||||||
|
username = prompt('Enter your username:');
|
||||||
|
if (!username) {
|
||||||
|
alert('Username is required!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create WebSocket connection
|
||||||
|
ws = new WebSocket('ws://localhost:8081/chat');
|
||||||
|
|
||||||
|
ws.onopen = () => {
|
||||||
|
console.log('Connected to WebSocket server');
|
||||||
|
statusDiv.textContent = 'Connected';
|
||||||
|
statusDiv.className = 'connected';
|
||||||
|
messageInput.disabled = false;
|
||||||
|
sendButton.disabled = false;
|
||||||
|
connectButton.textContent = 'Disconnect';
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onclose = () => {
|
||||||
|
console.log('Disconnected from WebSocket server');
|
||||||
|
statusDiv.textContent = 'Disconnected';
|
||||||
|
statusDiv.className = 'disconnected';
|
||||||
|
messageInput.disabled = true;
|
||||||
|
sendButton.disabled = true;
|
||||||
|
connectButton.textContent = 'Connect';
|
||||||
|
ws = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onerror = (error) => {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
|
alert('Error connecting to WebSocket server');
|
||||||
|
};
|
||||||
|
|
||||||
|
ws.onmessage = (event) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data);
|
||||||
|
addMessage(data.username, data.message, data.username === username);
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Error parsing message:', e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function disconnect() {
|
||||||
|
if (ws) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendMessage() {
|
||||||
|
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
||||||
|
alert('Not connected to server');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const message = messageInput.value.trim();
|
||||||
|
if (message) {
|
||||||
|
const data = {
|
||||||
|
username: username,
|
||||||
|
message: message
|
||||||
|
};
|
||||||
|
ws.send(JSON.stringify(data));
|
||||||
|
messageInput.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addMessage(username, message, isSent) {
|
||||||
|
const messageDiv = document.createElement('div');
|
||||||
|
messageDiv.className = `message ${isSent ? 'sent' : 'received'}`;
|
||||||
|
messageDiv.textContent = `${username}: ${message}`;
|
||||||
|
messagesDiv.appendChild(messageDiv);
|
||||||
|
messagesDiv.scrollTop = messagesDiv.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Event listeners
|
||||||
|
connectButton.addEventListener('click', () => {
|
||||||
|
if (ws) {
|
||||||
|
disconnect();
|
||||||
|
} else {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
sendButton.addEventListener('click', sendMessage);
|
||||||
|
|
||||||
|
messageInput.addEventListener('keypress', (e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
sendMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle page close/reload
|
||||||
|
window.addEventListener('beforeunload', () => {
|
||||||
|
if (ws) {
|
||||||
|
ws.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user