Przed uruchomieniem projektu upewnij się, że masz zainstalowane następujące narzędzia:
-
Docker - do konteneryzacji aplikacji
# Sprawdź, czy Docker jest zainstalowany docker --version # Jeśli nie, zainstaluj Docker według instrukcji ze strony https://docs.docker.com/get-docker/
-
Docker Compose - do orkiestracji kontenerów
# Sprawdź, czy Docker Compose jest zainstalowany docker-compose --version # Jeśli nie, zainstaluj Docker Compose według instrukcji ze strony https://docs.docker.com/compose/install/
-
curl - do testowania API
# Sprawdź, czy curl jest zainstalowany curl --version # Jeśli nie, zainstaluj curl # Na Ubuntu/Debian: sudo apt-get update && sudo apt-get install -y curl # Na macOS (używając Homebrew): brew install curl
-
jq (opcjonalnie) - do formatowania odpowiedzi JSON
# Sprawdź, czy jq jest zainstalowany jq --version # Jeśli nie, zainstaluj jq # Na Ubuntu/Debian: sudo apt-get update && sudo apt-get install -y jq # Na macOS (używając Homebrew): brew install jq
-
Sklonuj repozytorium projektu (jeśli jest dostępne) lub utwórz strukturę projektu:
# Utwórz strukturę projektu za pomocą skryptu instalacyjnego chmod +x setup.sh ./setup.sh -
Dostosuj plik
.envdo swoich potrzeb:# Otwórz plik .env w edytorze tekstu nano .env # Dostosuj ustawienia, szczególnie w sekcji EMAIL_* i OLLAMA_*
Użyj przygotowanego skryptu startowego:
# Nadaj uprawnienia wykonywania skryptowi
chmod +x start.sh
# Uruchom skrypt
./start.shSkrypt wykonuje następujące działania:
- Uruchamia kontenery Docker za pomocą docker-compose
- Czeka na uruchomienie serwera Ollama
- Pobiera model LLM, jeśli jest to konieczne (to może zająć kilka minut)
- Czeka na uruchomienie aplikacji
- Wyświetla dostępne endpointy
Po uruchomieniu aplikacji, sprawdź czy wszystkie usługi działają poprawnie:
-
API aplikacji: Otwórz w przeglądarce http://localhost:8080/api/health
- Powinieneś zobaczyć odpowiedź JSON ze statusem "UP"
-
Dokumentacja API: Otwórz w przeglądarce http://localhost:8080/api/api-doc
- Powinieneś zobaczyć interaktywną dokumentację API
-
Panel testowej skrzynki email: Otwórz w przeglądarce http://localhost:8025
- MailHog zapewnia interfejs webowy do podglądu testowych wiadomości email
-
Panel administracyjny SQLite: Otwórz w przeglądarce http://localhost:8081
- Wybierz SQLite jako typ bazy danych
- Jako server podaj "/data/emails.db"
- Pozostaw hasło puste
- Kliknij "Login" aby zarządzać bazą danych
Użyj przygotowanego skryptu do testowania API:
# Nadaj uprawnienia wykonywania skryptowi
chmod +x test-api.sh
# Uruchom skrypt
./test-api.shSkrypt wykonuje następujące zapytania:
- Sprawdza stan aplikacji (GET /api/health)
- Testuje analizę tekstu przez LLM (POST /api/llm/direct-analyze)
- Pobiera listę emaili (GET /api/emails)
Głównym zadaniem projektu jest zdefiniowanie tras w Apache Camel, które określają przepływ danych w systemie. Trasy można edytować w następujących miejscach:
-
Główne klasy aplikacji w katalogu
camel-groovy/src/main/groovy/com/example/emailllm/:EmailProcessingRoute.groovy- trasy do przetwarzania emailiMaintenanceRoutes.groovy- trasy dla zadań konserwacyjnychRestApiConfig.groovy- konfiguracja API REST
-
Dynamicznie ładowane trasy w katalogu
camel-groovy/routes/:OllamaDirectRoute.groovy- trasa do bezpośredniej integracji z Ollama LLM
Każdy plik zawiera komentarze "TO-DO", które wskazują miejsca wymagające uzupełnienia.
W pliku camel-groovy/routes/OllamaDirectRoute.groovy zaimplementuj pełną integrację z Ollama LLM:
// Endpoint REST API dla bezpośredniej analizy tekstu przez LLM
rest('/llm')
.post('/direct-analyze')
.description('Bezpośrednia analiza tekstu za pomocą LLM')
.consumes('application/json')
.produces('application/json')
.type(Map.class)
.outType(Map.class)
.route()
.process { exchange ->
def body = exchange.getIn().getBody(Map.class)
def text = body.text
def context = body.context ?: ""
// Przygotowanie zapytania dla Ollama
def prompt = """
Przeanalizuj poniższy tekst i:
1. Wyodrębnij kluczowe informacje i tematy
2. Określ priorytet i pilność
3. Zidentyfikuj czy wymagane są działania lub odpowiedzi
=== TEKST ===
${text}
${context ? "=== KONTEKST ===\n${context}" : ""}
Odpowiedz w formacie JSON z następującymi polami:
{
"keyTopics": ["temat1", "temat2"],
"priority": "high/medium/low",
"requiresResponse": true/false,
"actionRequired": true/false,
"summary": "krótkie podsumowanie"
}
"""
// Przygotowanie requestu do Ollama
def requestBody = [
model: ollamaModel,
prompt: prompt,
stream: false
]
exchange.getIn().setBody(JsonOutput.toJson(requestBody))
exchange.getIn().setHeader('CamelHttpMethod', 'POST')
exchange.getIn().setHeader('Content-Type', 'application/json')
}
.to("http://${ollamaHost}/api/generate")
.unmarshal().json()
.process { exchange ->
def response = exchange.getIn().getBody(Map.class)
def jsonSlurper = new JsonSlurper()
def analysis
try {
// Próba parsowania JSON z odpowiedzi LLM
analysis = jsonSlurper.parseText(response.response)
} catch (Exception e) {
// Jeśli odpowiedź nie jest poprawnym JSON, zwróć surową odpowiedź
analysis = [
raw_response: response.response,
processed: false,
error: "Nie można sparsować odpowiedzi jako JSON"
]
}
exchange.getIn().setBody([
result: analysis,
model: response.model,
processing_time: response.processing_time,
timestamp: LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
])
}
.endRest()W pliku camel-groovy/src/main/groovy/com/example/emailllm/EmailProcessingRoute.groovy zaimplementuj trasę do przetwarzania emaili:
// Trasa do monitorowania emaili
from("imaps://${imapHost}:${imapPort}?" +
"username=${emailUser}&password=${emailPassword}&" +
"folderName=${imapFolder}&unseen=true&" +
"consumer.delay=60000")
.routeId("email-polling")
.log(LoggingLevel.INFO, "Odebrano nowy email: ${header.subject}")
.process { exchange ->
// Pobierz wiadomość email
def mailMessage = exchange.getIn()
def mimeMessage = mailMessage.getBody(javax.mail.internet.MimeMessage.class)
// Ekstrahuj dane z wiadomości
def emailData = [
messageId: mimeMessage.getMessageID(),
subject: mimeMessage.getSubject(),
sender: mimeMessage.getFrom()[0].toString(),
recipients: mimeMessage.getAllRecipients()*.toString().join(", "),
receivedDate: mimeMessage.getSentDate() ?
mimeMessage.getSentDate().toInstant()
.atZone(java.time.ZoneId.systemDefault())
.toLocalDateTime()
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) :
LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME),
bodyText: extractTextFromMessage(mimeMessage),
status: "pending"
]
exchange.getIn().setBody(emailData)
}
.to("direct:analyzeLLM")
.process { exchange ->
def emailData = exchange.getIn().getBody(Map.class)
def llmAnalysis = exchange.getIn().getHeader("LLMAnalysis", Map.class)
// Połącz dane emaila z analizą LLM
emailData.llmAnalysis = JsonOutput.toJson(llmAnalysis)
emailData.status = "processed"
emailData.processedDate = LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
exchange.getIn().setBody(emailData)
}
.to("sql:INSERT INTO processed_emails (message_id, subject, sender, recipients, received_date, processed_date, body_text, status, llm_analysis) VALUES (:#messageId, :#subject, :#sender, :#recipients, :#receivedDate, :#processedDate, :#bodyText, :#status, :#llmAnalysis)?dataSource=dataSource")
.log(LoggingLevel.INFO, "Email zapisany w bazie danych: ${body.messageId}")Aby zatrzymać projekt, użyj skryptu zatrzymującego:
# Nadaj uprawnienia wykonywania skryptowi
chmod +x stop.sh
# Uruchom skrypt
./stop.shSkrypt zatrzymuje wszystkie kontenery Docker uruchomione przez docker-compose.
Objaw: Aplikacja zgłasza błędy połączenia z serwerem Ollama
Rozwiązanie:
- Sprawdź, czy kontener Ollama jest uruchomiony:
docker ps | grep ollama - Sprawdź logi kontenera Ollama:
docker logs ollama
- Upewnij się, że Ollama ma wystarczającą ilość pamięci (co najmniej 4GB):
docker stats ollama
Objaw: Zapytania do bazy danych zwracają błędy lub puste wyniki
Rozwiązanie:
- Sprawdź, czy katalog
dataistnieje i ma odpowiednie uprawnienia:ls -la data
- Sprawdź logi kontenera aplikacji:
docker logs camel-groovy-email-llm
- Spróbuj ręcznie utworzyć bazę danych:
docker exec -it camel-groovy-email-llm /app/scripts/entrypoint.sh
Objaw: Nie można połączyć się z API aplikacji
Rozwiązanie:
- Sprawdź, czy kontener aplikacji jest uruchomiony:
docker ps | grep camel-groovy - Sprawdź logi kontenera aplikacji:
docker logs camel-groovy-email-llm
- Uruchom ponownie kontener aplikacji:
docker restart camel-groovy-email-llm
Pełna dokumentacja projektu znajduje się w pliku documentation.md, który zawiera:
- Szczegółowe diagramy przepływu danych
- Opis architektury systemu
- Dokumentację API REST
- Najlepsze praktyki