saved
This commit is contained in:
36
CSV.py
Normal file
36
CSV.py
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import json, csv, os, time, stomp
|
||||||
|
from datetime import datetime
|
||||||
|
from flask_backend.Stomp_client import get_connection
|
||||||
|
|
||||||
|
QUEUE_NAME = "/queue/testQueue"
|
||||||
|
OUTPUT_DIR = "/app/output"
|
||||||
|
os.makedirs(OUTPUT_DIR, exist_ok=True)
|
||||||
|
|
||||||
|
class MyListener(stomp.ConnectionListener):
|
||||||
|
def on_message(self, frame):
|
||||||
|
try:
|
||||||
|
data = json.loads(frame.body)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
print("Received invalid JSON:", frame.body)
|
||||||
|
return
|
||||||
|
|
||||||
|
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||||
|
filename = os.path.join(OUTPUT_DIR, f"message_{timestamp}.csv")
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filename, "w", newline="") as f:
|
||||||
|
writer = csv.writer(f)
|
||||||
|
writer.writerow(data.keys())
|
||||||
|
writer.writerow(data.values())
|
||||||
|
print(f"Saved CSV: {filename}")
|
||||||
|
except Exception as e:
|
||||||
|
print("Error writing CSV:", e)
|
||||||
|
|
||||||
|
# Připojení k ActiveMQ s listenerem
|
||||||
|
listener = MyListener()
|
||||||
|
conn = get_connection(listener=listener)
|
||||||
|
conn.subscribe(destination=QUEUE_NAME, id=1, ack="auto")
|
||||||
|
|
||||||
|
# keep process alive
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
9
Dockerfile
Normal file
9
Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
27
README.md
27
README.md
@@ -1,2 +1,29 @@
|
|||||||
# Titeto-WSO2-ActiveMQ
|
# Titeto-WSO2-ActiveMQ
|
||||||
|
|
||||||
|
## WSO2 API Manager
|
||||||
|
3. Vytvor jednoduche rest api v WSO2 API manageru s resource POST.
|
||||||
|
|
||||||
|
|
||||||
|
## Flask
|
||||||
|
4. Vytvor Python script ktery bude fungovat jako rest API, a jeho endpoint pouzij v API manageru.
|
||||||
|
|
||||||
|
5. Rest API bude prijmat XML jako input_payload.
|
||||||
|
|
||||||
|
6. Rest API tento payload odesle na backend do python scriptu.
|
||||||
|
|
||||||
|
## Sender.py
|
||||||
|
7. Vytvor JSON payload s mappingem viz. attachment a priklady output payloadu.
|
||||||
|
|
||||||
|
8. Script posle payload jako zpravu do vytvorene Q v ActiveMQ.
|
||||||
|
|
||||||
|
9. Posli vyslednou response s HTTP-SC.
|
||||||
|
|
||||||
|
## Active MQ
|
||||||
|
|
||||||
|
## CSV.py
|
||||||
|
|
||||||
|
10. Vytvor dalsi script ktery bude naslouchat na vytvorenou Q.
|
||||||
|
|
||||||
|
11. Vytvor CSV file dle prikladu viz. attachment.
|
||||||
|
|
||||||
|
12. Uloz CSV s filename viz. diagram s aktualni timestampou, do libovolne slozky na lokalu.
|
||||||
67
docker-compose.yml
Normal file
67
docker-compose.yml
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
version: "3.8"
|
||||||
|
|
||||||
|
services:
|
||||||
|
# 🐍 Flask REST API
|
||||||
|
flask_backend:
|
||||||
|
build: .
|
||||||
|
container_name: flask_backend
|
||||||
|
ports:
|
||||||
|
- "5000:5000"
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
command: ["python", "flask_backend/app.py"]
|
||||||
|
depends_on:
|
||||||
|
- activemq
|
||||||
|
|
||||||
|
|
||||||
|
# 📨 ActiveMQ
|
||||||
|
activemq:
|
||||||
|
image: rmohr/activemq:5.15.9
|
||||||
|
container_name: activemq
|
||||||
|
ports:
|
||||||
|
- "61613:61613" # STOMP port (pro komunikaci s Pythonem)
|
||||||
|
- "8161:8161" # Web UI: http://localhost:8161/admin
|
||||||
|
environment:
|
||||||
|
ACTIVEMQ_ADMIN_LOGIN: admin
|
||||||
|
ACTIVEMQ_ADMIN_PASSWORD: admin
|
||||||
|
restart: always
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
|
||||||
|
receiving_consumer:
|
||||||
|
build: .
|
||||||
|
container_name: CSV_python
|
||||||
|
depends_on:
|
||||||
|
- activemq
|
||||||
|
environment:
|
||||||
|
MQ_HOST: activemq
|
||||||
|
MQ_PORT: 61613
|
||||||
|
MQ_USER: admin
|
||||||
|
MQ_PASS: admin
|
||||||
|
command: ["python", "CSV.py"]
|
||||||
|
volumes:
|
||||||
|
- ./output:/app/output # ✅ CSV soubory se uloží do ./output na tvém disku
|
||||||
|
restart: on-failure
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
# odešle na Flask API testovací XML zprávu
|
||||||
|
wso2apim:
|
||||||
|
image: wso2/wso2am:3.2.0
|
||||||
|
container_name: wso2apim
|
||||||
|
volumes:
|
||||||
|
- ./wso2/deployment.toml:/home/wso2carbon/wso2am-3.2.0/repository/conf/deployment.toml
|
||||||
|
- ./data/activemq:/opt/activemq/data
|
||||||
|
ports:
|
||||||
|
- "9443:9443" # HTTPS Management Console
|
||||||
|
- "8280:8280" # HTTP Gateway
|
||||||
|
- "8243:8243" # HTTPS Gateway
|
||||||
|
environment:
|
||||||
|
- JAVA_OPTS=-Duser.timezone=UTC
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
|
||||||
|
networks:
|
||||||
|
internal:
|
||||||
|
driver: bridge
|
||||||
9
flask_backend/Dockerfile
Normal file
9
flask_backend/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
COPY ../requirements.txt .
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir -r ../requirements.txt
|
||||||
|
|
||||||
|
COPY . .
|
||||||
14
flask_backend/Sender.py
Normal file
14
flask_backend/Sender.py
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import json
|
||||||
|
from Stomp_client import get_connection
|
||||||
|
|
||||||
|
QUEUE_NAME = "/queue/testQueue"
|
||||||
|
|
||||||
|
def send_to_queue(payload: dict):
|
||||||
|
"""
|
||||||
|
Posílá JSON payload do ActiveMQ queue, přijíma dic
|
||||||
|
"""
|
||||||
|
conn = get_connection() # připojení s retry loop
|
||||||
|
conn.send(destination=QUEUE_NAME, body=json.dumps(payload))
|
||||||
|
print("Message sent to ActiveMQ:", payload)
|
||||||
|
conn.disconnect()
|
||||||
|
|
||||||
25
flask_backend/Stomp_client.py
Normal file
25
flask_backend/Stomp_client.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import stomp, os, time
|
||||||
|
|
||||||
|
MQ_HOST = os.getenv("MQ_HOST", "activemq")
|
||||||
|
MQ_PORT = int(os.getenv("MQ_PORT", 61613))
|
||||||
|
MQ_USER = os.getenv("MQ_USER", "admin")
|
||||||
|
MQ_PASS = os.getenv("MQ_PASS", "admin")
|
||||||
|
|
||||||
|
def get_connection(listener=None):
|
||||||
|
"""
|
||||||
|
Vrací připojený STOMP Connection objekt.
|
||||||
|
Pokud listener je None, připojení bude bez listeneru.
|
||||||
|
"""
|
||||||
|
conn = stomp.Connection12([(MQ_HOST, MQ_PORT)])
|
||||||
|
if listener:
|
||||||
|
conn.set_listener("", listener)
|
||||||
|
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
conn.connect(MQ_USER, MQ_PASS, wait=True)
|
||||||
|
print("Connected to ActiveMQ")
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
print("Waiting for ActiveMQ to be ready...", e)
|
||||||
|
time.sleep(3)
|
||||||
|
return conn
|
||||||
20
flask_backend/app.py
Normal file
20
flask_backend/app.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
from flask import Flask, request, jsonify
|
||||||
|
from Sender import send_to_queue
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route("/send", methods=["POST"])
|
||||||
|
def send():
|
||||||
|
# očekává JSON payload
|
||||||
|
payload = request.get_json()
|
||||||
|
if not payload:
|
||||||
|
return jsonify({"error": "No JSON payload provided"}), 400
|
||||||
|
|
||||||
|
try:
|
||||||
|
send_to_queue(payload) # voláme funkci z sender.py
|
||||||
|
return jsonify({"status": "ok"}), 200
|
||||||
|
except Exception as e:
|
||||||
|
return jsonify({"error": str(e)}), 500
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app.run(host="0.0.0.0", port=5000)
|
||||||
19
flask_backend/templates/index.html
Normal file
19
flask_backend/templates/index.html
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Upload the </h1>
|
||||||
|
<form action="/manage/John" method="post">
|
||||||
|
<button type="submit">Manage John</button>
|
||||||
|
</form>
|
||||||
|
<form action="/page/Jane" method="post">
|
||||||
|
<button type="submit">Go to Jane's Page</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{{ message }}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
65
misc/inputs/Input_payload.xml
Normal file
65
misc/inputs/Input_payload.xml
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soapenv:Body>
|
||||||
|
<actor>
|
||||||
|
<list>
|
||||||
|
<id>59088032</id>
|
||||||
|
<firstName>Jiri Novak</firstName>
|
||||||
|
<lastName>Vika</lastName>
|
||||||
|
<address>
|
||||||
|
<streetName>StreetName</streetName>
|
||||||
|
<postCode>4312</postCode>
|
||||||
|
<cityName>SANDNES</cityName>
|
||||||
|
<countryCode>NO</countryCode>
|
||||||
|
<isPostBox>true</isPostBox>
|
||||||
|
</address>
|
||||||
|
<addressLine1>StreetName 1A</addressLine1>
|
||||||
|
<country>NORWAY</country>
|
||||||
|
<phoneNumber>+4793488400</phoneNumber>
|
||||||
|
<cellularPhoneNumber>+4793488999</cellularPhoneNumber>
|
||||||
|
<emailAddress>testguy@gmail.com</emailAddress>
|
||||||
|
<dateOfBirth>1962-10-01</dateOfBirth>
|
||||||
|
<hasSecretAddress>false</hasSecretAddress>
|
||||||
|
<isReservedAgainstSalesMaterial>false</isReservedAgainstSalesMaterial>
|
||||||
|
</list>
|
||||||
|
<list>
|
||||||
|
<id>59088033</id>
|
||||||
|
<firstName>Tomas Novak</firstName>
|
||||||
|
<lastName>Vika</lastName>
|
||||||
|
<address>
|
||||||
|
<streetName>Postboks 16</streetName>
|
||||||
|
<postCode>4318</postCode>
|
||||||
|
<cityName>BERGEN</cityName>
|
||||||
|
<countryCode>NO</countryCode>
|
||||||
|
<isPostBox>true</isPostBox>
|
||||||
|
</address>
|
||||||
|
<addressLine1>StreetName 1B</addressLine1>
|
||||||
|
<country>NORWAY</country>
|
||||||
|
<phoneNumber>+4793488888</phoneNumber>
|
||||||
|
<emailAddress>testguy2@gmail.com</emailAddress>
|
||||||
|
<dateOfBirth>1963-10-01</dateOfBirth>
|
||||||
|
<hasSecretAddress>false</hasSecretAddress>
|
||||||
|
<isReservedAgainstSalesMaterial>false</isReservedAgainstSalesMaterial>
|
||||||
|
</list>
|
||||||
|
<list>
|
||||||
|
<id>59088034</id>
|
||||||
|
<firstName>Karel Novak</firstName>
|
||||||
|
<lastName>Vika</lastName>
|
||||||
|
<address>
|
||||||
|
<streetName>StreetName</streetName>
|
||||||
|
<postCode>4319</postCode>
|
||||||
|
<cityName>STAVANGER</cityName>
|
||||||
|
<countryCode>NO</countryCode>
|
||||||
|
<isPostBox>true</isPostBox>
|
||||||
|
</address>
|
||||||
|
<addressLine1>StreetName 1C</addressLine1>
|
||||||
|
<country>NORWAY</country>
|
||||||
|
<phoneNumber>+4793488777</phoneNumber>
|
||||||
|
<emailAddress>testguy3@gmail.com</emailAddress>
|
||||||
|
<dateOfBirth>1964-10-01</dateOfBirth>
|
||||||
|
<hasSecretAddress>false</hasSecretAddress>
|
||||||
|
<isReservedAgainstSalesMaterial>false</isReservedAgainstSalesMaterial>
|
||||||
|
</list>
|
||||||
|
</actor>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>
|
||||||
56
misc/inputs/Output_file_AMQ.json
Normal file
56
misc/inputs/Output_file_AMQ.json
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
{
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"id": 59088032,
|
||||||
|
"firstName": "Jiri Novak",
|
||||||
|
"lastName": "Vika",
|
||||||
|
"streetName": "StreetName",
|
||||||
|
"postCode": 4312,
|
||||||
|
"cityName": "SANDNES",
|
||||||
|
"countryCode": "NO",
|
||||||
|
"isPostBox": true,
|
||||||
|
"addressLine1": "StreetName 1A",
|
||||||
|
"country": "NORWAY",
|
||||||
|
"phoneNumber": 4793488400,
|
||||||
|
"cellularPhoneNumber": 4793488999,
|
||||||
|
"emailAddress": "testguy@gmail.com",
|
||||||
|
"dateOfBirth": "1962-10-01",
|
||||||
|
"hasSecretAddress": false,
|
||||||
|
"isReservedAgainstSalesMaterial": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 59088033,
|
||||||
|
"firstName": "Tomas Novak",
|
||||||
|
"lastName": "Vika",
|
||||||
|
"streetName": "Postboks 16",
|
||||||
|
"postCode": 4318,
|
||||||
|
"cityName": "BERGEN",
|
||||||
|
"countryCode": "NO",
|
||||||
|
"isPostBox": true,
|
||||||
|
"addressLine1": "StreetName 1B",
|
||||||
|
"country": "NORWAY",
|
||||||
|
"phoneNumber": 4793488888,
|
||||||
|
"emailAddress": "testguy2@gmail.com",
|
||||||
|
"dateOfBirth": "1963-10-01",
|
||||||
|
"hasSecretAddress": false,
|
||||||
|
"isReservedAgainstSalesMaterial": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 59088034,
|
||||||
|
"firstName": "Karel Novak",
|
||||||
|
"lastName": "Vika",
|
||||||
|
"streetName": "StreetName",
|
||||||
|
"postCode": 4319,
|
||||||
|
"cityName": "STAVANGER",
|
||||||
|
"countryCode": "NO",
|
||||||
|
"isPostBox": true,
|
||||||
|
"addressLine1": "StreetName 1C",
|
||||||
|
"country": "NORWAY",
|
||||||
|
"phoneNumber": 4793488777,
|
||||||
|
"emailAddress": "testguy3@gmail.com",
|
||||||
|
"dateOfBirth": "1964-10-01",
|
||||||
|
"hasSecretAddress": false,
|
||||||
|
"isReservedAgainstSalesMaterial": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
3
misc/output/Output_file.csv
Normal file
3
misc/output/Output_file.csv
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
list;59088032;Jiri Novak;Vika;StreetName;4312;Sandnes;NO;true;StreetName;StreetName 1A;NORWAY;+4793488400;+4793488999;testguy@gmail.com;1962-10-01;false;false
|
||||||
|
list;59088033;Tomas Novak;Vika;StreetName;4318;Bergen;NO;true;Postboks 16;StreetName 1B;NORWAY;+4793488888;;testguy2@gmail.com;1963-10-01;false;false
|
||||||
|
list;59088034;Karel Novak;Vika;StreetName;4319;Stavanger;NO;true;StreetName;StreetName 1C;NORWAY;+4793488777;;testguy3@gmail.com;1964-10-01;false;false
|
||||||
|
BIN
misc/schéma.png
Normal file
BIN
misc/schéma.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
flask
|
||||||
|
stomp.py
|
||||||
|
xmltodict
|
||||||
4
wso2/deployment.toml
Normal file
4
wso2/deployment.toml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
[super_admin]
|
||||||
|
username = "admin"
|
||||||
|
password = "admin"
|
||||||
|
create_admin_account = true
|
||||||
Reference in New Issue
Block a user