Skip to content
Open
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
9 changes: 6 additions & 3 deletions MQTT/pub.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# Inisialisasi topik dan pesan suhu
topic = "sister/temp"
suhu = 28 # Suhu tetap 28'C
lokasi = "Jakarta"

# Callback untuk koneksi
def on_connect(client, userdata, flags, rc, properties=None):
Expand All @@ -41,11 +42,13 @@ def on_connect(client, userdata, flags, rc, properties=None):
# Loop untuk mengirim pesan setiap detik
try:
while True:
# Mempublikasikan suhu ke topik
message = f"Suhu: {suhu}°C"
# Mempublikasikan payload yang berisi suhu dan lokasi sebagai JSON
payload = {"suhu": suhu, "lokasi": lokasi}
import json
message = json.dumps(payload)
client.publish(topic, message)
print(f"Published: {message}")

# Tunggu 1 detik sebelum mengirim lagi
time.sleep(1)

Expand Down
10 changes: 9 additions & 1 deletion MQTT/sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,15 @@ def on_connect(client, userdata, flags, rc, properties=None):

# Callback untuk pesan yang diterima
def on_message(client, userdata, message, properties=None):
print(f"Received message: {message.payload.decode()} (Topic: {message.topic})")
payload = message.payload.decode()
try:
import json
data = json.loads(payload)
suhu = data.get('suhu')
lokasi = data.get('lokasi')
print(f"Diterima: Suhu = {suhu}°C, Lokasi = {lokasi} (Topic: {message.topic})")
except Exception:
print(f"Received message: {payload} (Topic: {message.topic})")

# Inisialisasi klien MQTT dengan API versi terbaru
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
Expand Down
11 changes: 9 additions & 2 deletions REST/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
import requests
import argparse
import sys
import os

BASE = 'http://rest-server:5151'
BASE = os.environ.get('REST_BASE', 'http://rest-server:5151')

def call(endpoint, a, b):
try:
Expand All @@ -23,16 +24,22 @@ def call(endpoint, a, b):
except Exception as e:
print(f"{endpoint} exception: {e}")


def main():
parser = argparse.ArgumentParser(description="Simple REST client for add/mul endpoints")
parser.add_argument('--op', choices=['add','mul','both'], default='both', help='Operation to invoke')
parser.add_argument('--op', choices=['add','mul','both','sub','div'], default='both', help='Operation to invoke')
parser.add_argument('-a', type=int, default=10)
parser.add_argument('-b', type=int, default=5)
args = parser.parse_args()
if args.op in ('add','both'):
call('add', args.a, args.b)
if args.op in ('mul','both'):
call('mul', args.a, args.b)
if args.op in ('sub','both'):
call('sub', args.a, args.b)
if args.op in ('div','both'):
call('div', args.a, args.b)


if __name__ == '__main__':
sys.exit(main())
89 changes: 73 additions & 16 deletions REST/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,41 +6,98 @@
@author: widhi
"""

import os
from flask import Flask, request, jsonify

# Inisialisasi aplikasi Flask
app = Flask(__name__)

# Endpoint untuk pengurangan

@app.route('/add', methods=['GET'])
def sub_numbers():
def add_numbers():
try:
# Mengambil parameter a dan b dari query string
a = int(request.args.get('a'))
b = int(request.args.get('b'))
result = a + b
return jsonify({'result': a + b})
except (TypeError, ValueError):
return jsonify({'error': 'Invalid input'}), 400

# Mengembalikan hasil dalam format JSON
return jsonify({'result': result})

@app.route('/sub', methods=['GET'])
def sub_numbers():
try:
a = int(request.args.get('a'))
b = int(request.args.get('b'))
return jsonify({'result': a - b})
except (TypeError, ValueError):
# Menangani error jika input tidak valid
return jsonify({'error': 'Invalid input'}), 400



@app.route('/mul', methods=['GET'])
def mul_numbers():
try:
# Mengambil parameter a dan b dari query string
a = int(request.args.get('a'))
b = int(request.args.get('b'))
result = a * b

# Mengembalikan hasil dalam format JSON
return jsonify({'result': result})
return jsonify({'result': a * b})
except (TypeError, ValueError):
# Menangani error jika input tidak valid
return jsonify({'error': 'Invalid input'}), 400

# Jalankan server di port 5000

@app.route('/div', methods=['GET'])
def div_numbers():
try:
a = int(request.args.get('a'))
b = int(request.args.get('b'))
if b == 0:
return jsonify({'error': 'Division by zero'}), 400
return jsonify({'result': a / b})
except (TypeError, ValueError):
return jsonify({'error': 'Invalid input'}), 400


@app.route('/calc', methods=['POST'])
def calc():
"""Generic calculator endpoint. Accepts JSON body: {"op": "add|sub|mul|div", "a": <num>, "b": <num>}"""
data = request.get_json(silent=True)
if not data:
return jsonify({'error': 'JSON body required'}), 400

op = data.get('op')
a = data.get('a')
b = data.get('b')
try:
a = float(a)
b = float(b)
except (TypeError, ValueError):
return jsonify({'error': 'Invalid input'}), 400

if op == 'add':
res = a + b
elif op == 'sub':
res = a - b
elif op == 'mul':
res = a * b
elif op == 'div':
if b == 0:
return jsonify({'error': 'Division by zero'}), 400
res = a / b
elif op == 'mod':
# modulo operation
if b == 0:
return jsonify({'error': 'Division by zero'}), 400
res = a % b
elif op == 'pow':
# exponentiation
res = a ** b
else:
return jsonify({'error': 'Unknown operation'}), 400

return jsonify({'result': res})


if __name__ == '__main__':
# Read PORT from environment to allow container/host mapping flexibility
port = int(os.environ.get('PORT', '5151'))
print(f"Starting REST server on 0.0.0.0:{port} (debug=True)")
# Bind to 0.0.0.0 so container port mapping works externally
app.run(debug=True, host='0.0.0.0', port=5151)
app.run(debug=True, host='0.0.0.0', port=port)
142 changes: 134 additions & 8 deletions SOAP/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,143 @@

@author: widhi
"""
import argparse
import os
import json
import time
from datetime import datetime
from zeep import Client

# URL WSDL menggunakan nama service Docker Compose
wsdl = 'http://soap-server:8000/?wsdl'

# Membuat klien SOAP berdasarkan WSDL
client = Client(wsdl=wsdl)
def main():
parser = argparse.ArgumentParser(description='SOAP client CLI for calculator service')
parser.add_argument('--wsdl', default=os.environ.get('SOAP_WSDL', 'http://soap-server:8000/?wsdl'), help='WSDL URL or env SOAP_WSDL')
parser.add_argument('--op', choices=['add', 'sub', 'mul', 'div','mod','pow','avg'], default=None, help='Operation (if omitted, client will print combined add+sub sentence)')
parser.add_argument('--all', action='store_true', help='Run all supported operations')
parser.add_argument('-a', type=int, default=10)
parser.add_argument('-b', type=int, default=5)
parser.add_argument('--repeat', type=int, default=1, help='Repeat each operation N times and report average latency')
parser.add_argument('--combined', action='store_true', help='Print combined sentence for add and sub in Indonesian')
parser.add_argument('--json-output', action='store_true', help='Print output as JSON')
parser.add_argument('--verbose', action='store_true', help='Print verbose output (timestamp, wsdl, latency)')
args = parser.parse_args()

# Memanggil metode penjumlahan dari layanan SOAP server
result = client.service.add(10, 5)
client = Client(wsdl=args.wsdl)
# If user didn't provide --op, --all, or --combined, default to combined sentence
if args.op is None and not args.all and not args.combined:
args.combined = True
try:
ops = ['add', 'sub', 'mul', 'div', 'mod', 'pow', 'avg']

# Menampilkan hasil penjumlahan
print(f'Hasil penjumlahan dari server SOAP: {result}')
def call_one(op_name):
# call op_name once and return (result, latency_ms)
start = time.perf_counter()
if op_name == 'add':
r = client.service.add(args.a, args.b)
elif op_name == 'sub':
r = client.service.sub(args.a, args.b)
elif op_name == 'mul':
r = client.service.mul(args.a, args.b)
elif op_name == 'div':
r = client.service.div(args.a, args.b)
elif op_name == 'mod':
r = client.service.mod(args.a, args.b)
elif op_name == 'pow':
r = client.service.pow(args.a, args.b)
elif op_name == 'avg':
r = client.service.avg(args.a, args.b)
else:
raise ValueError('Unknown op')
end = time.perf_counter()
return r, (end - start) * 1000.0

results = []

if args.combined:
# Call add and sub and print combined Indonesian sentence
# perform repeats and take the last result for display (and avg latency)
def call_n(op_name):
total_latency = 0.0
res_val = None
for i in range(max(1, args.repeat)):
r, lat = call_one(op_name)
total_latency += lat
res_val = r
avg_latency = total_latency / max(1, args.repeat)
return res_val, avg_latency

add_res, add_lat = call_n('add')
sub_res, sub_lat = call_n('sub')

if args.json_output:
out = {
'timestamp': datetime.utcnow().isoformat() + 'Z',
'wsdl': args.wsdl,
'add': add_res,
'sub': sub_res,
'add_latency_ms': add_lat,
'sub_latency_ms': sub_lat,
'combined': f"hasil penjumlahan dengan SOAP = {add_res} dan hasil pengurangan dengan SOAP = {sub_res}"
}
print(json.dumps(out, indent=2))
else:
print(f"hasil penjumlahan dengan SOAP = {add_res} dan hasil pengurangan dengan SOAP = {sub_res}")
return

if args.all:
for op_name in ops:
total_latency = 0.0
total_res = 0.0
res_val = None
for i in range(max(1, args.repeat)):
r, lat = call_one(op_name)
total_latency += lat
try:
total_res += float(r)
except Exception:
total_res += 0.0
res_val = r
avg_latency = total_latency / max(1, args.repeat)
avg_result = total_res / max(1, args.repeat)
results.append({'op': op_name, 'a': args.a, 'b': args.b, 'result': res_val, 'avg_result': avg_result, 'latency_ms': avg_latency})
else:
total_latency = 0.0
total_res = 0.0
res_val = None
for i in range(max(1, args.repeat)):
r, lat = call_one(args.op)
total_latency += lat
try:
total_res += float(r)
except Exception:
total_res += 0.0
res_val = r
avg_latency = total_latency / max(1, args.repeat)
avg_result = total_res / max(1, args.repeat)
results.append({'op': args.op, 'a': args.a, 'b': args.b, 'result': res_val, 'avg_result': avg_result, 'latency_ms': avg_latency})

# Output
if args.json_output:
out = {
'timestamp': datetime.utcnow().isoformat() + 'Z',
'wsdl': args.wsdl,
'repeat': args.repeat,
'results': results,
}
print(json.dumps(out, indent=2))
else:
if args.verbose:
print(f"WSDL: {args.wsdl}")
print(f"Timestamp: {datetime.utcnow().isoformat()}Z")
for r in results:
if args.verbose:
print(f"{r['op']}({r['a']},{r['b']}) = {r['result']} (avg_result={r['avg_result']}, latency={r['latency_ms']:.2f} ms)")
else:
print(f"{r['op']}({r['a']},{r['b']}) = {r['result']}")
except Exception as e:
print('SOAP call failed:', e)


if __name__ == '__main__':
main()

34 changes: 33 additions & 1 deletion SOAP/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@author: widhi
"""

from spyne import Application, rpc, ServiceBase, Integer
from spyne import Application, rpc, ServiceBase, Integer, Double
from spyne.protocol.soap import Soap11
from spyne.server.wsgi import WsgiApplication

Expand All @@ -16,6 +16,38 @@ class CalculatorService(ServiceBase):
def add(ctx, a, b):
return a + b

@rpc(Integer, Integer, _returns=Integer)
def sub(ctx, a, b):
return a - b

@rpc(Integer, Integer, _returns=Integer)
def mul(ctx, a, b):
return a * b

@rpc(Integer, Integer, _returns=Integer)
def div(ctx, a, b):
# simple integer division; return 0 on division by zero
try:
return a // b
except ZeroDivisionError:
return 0

@rpc(Integer, Integer, _returns=Integer)
def mod(ctx, a, b):
try:
return a % b
except ZeroDivisionError:
return 0

@rpc(Integer, Integer, _returns=Double)
def pow(ctx, a, b):
# exponentiation; return float to avoid overflow issues
return float(a) ** float(b)

@rpc(Integer, Integer, _returns=Double)
def avg(ctx, a, b):
return (float(a) + float(b)) / 2.0

# Membuat aplikasi SOAP dengan protokol Soap11
app = Application([CalculatorService],
tns='spyne.examples.calculator',
Expand Down
Loading