# IS213 ESD — Finals Study Reference *Organized by the 10 Revision Groups from W12. Every section maps to lecture modules, mini-cases, and labs signaled by the prof as exam-critical.* --- ## How to use this document 1. **First pass**: read top to bottom, don't memorize — just build the mental map 2. **Second pass**: drill the "X vs Y" tables and scenario triggers (these are the exam questions in disguise) 3. **Third pass**: close this doc, open the HTML quiz app, test recall 4. **Night before**: skim only the red-flag sections marked ⚡ --- # GROUP 1 — Enterprise Applications & Business Processes *Maps to: W1.2 · Mini Case 1 (Categories)* ## Core concept A **business process** = a sequence of activities in an enterprise. Each activity often relies on **enterprise applications** (= IT systems = software systems — treated as synonyms in this course). An **enterprise solution** = one or more enterprise applications that produce, process, and exchange data to fulfill business requirements. Role of an enterprise app in a business process: provide UI · apply business rules · analyze/produce/store/retrieve data · send data to another app. ## ⚡ Three categories of enterprise applications | Category | Definition | Pros | Cons | |---|---|---|---| | **COTS** (Commercial-Off-The-Shelf) | Bought from external vendor, pre-built with best practices, not customer-specific | Out-of-box functionality, reliable, tech support, easier data exchange if standardized APIs | Limited flexibility (vendor owns it), expensive licensing, proprietary tech may block integration | | **Custom** | Built from scratch (in-house or external devs) per customer specs | Fully tailored, fits exact needs | Expensive, long lead time, documentation-critical, harder to exchange with other enterprises' apps | | **Legacy** | Old systems (20+ yrs), built with outdated tech | Stable, still provides needed functionality | Incompatible formats/interfaces, hard to integrate with newer apps, expensive to maintain | ## Two persistent challenges (these recur the whole course) 1. How to make apps **easily adaptable** to changing requirements? 2. How to enable **data exchange** among heterogeneous apps? → These two challenges are the *reason* SOA/MSA exist. ## Amazon bookstore sample apps (used throughout course) - **Product Management System** — product details, inventory alerts - **CRM** — customer details, sales opportunities - **Accounting** — total price, invoice, financial statements - **Delivery System** — shipping orders, courier notices --- # GROUP 2 — Monolith vs Microservice & MSA *Maps to: W1.3 · W2.1 · W11 Al Hilal · Al Hilal PDF* ## Monolithic Architecture Three-tier (analogous to MVC): **User Interface + Server + Database**, deployed as a single package (e.g., one `.war`, one PHP folder). ### Monolith characteristics - Single code base covering all functions - One programming language, one platform - Deployment is all-or-none (change one function → redeploy entire app) - Can't scale one function independently - Over time becomes large, complex, tightly coupled ## Microservice **A single unit that implements only one or a few functionalities, usable over the network via a standard interface independent of programming languages and platforms.** ### Microservice characteristics (the "independence" test) - **Own programming language** (one in Java, another in Python) - **Own platform** (one on Windows, another on Linux) - **Own data store** (each with its own DB table when needed) - **Scaled independently** (deploy extra instances of hot services) - **Changed independently** (as long as interface stays the same) - "Loosely coupled" with each other - Managed by a small agile team (**two-pizza team rule**) ## ⚡ Monolith vs MSA — pros/cons | Aspect | Monolith | Microservices | |---|---|---| | **Coupling** | Tight | Loose | | **Deployment** | All or none | Each service independently | | **Scaling** | Whole app | Per-service | | **Tech diversity** | One stack | Polyglot | | **Team structure** | Large single team | Many small agile teams | | **Dev overhead** | Low (function calls) | High (IPC, JSON over HTTP, error handling, network) | | **CI/CD friendliness** | Low | High | | **Complexity of interactions** | Internal (simpler to trace) | Across network (harder to test/debug) | | **Failure modes** | All down together | Partial failures possible | ## ⚡ When is monolith actually better? - Small/simple app - Team is small & co-located - Low need for independent scaling - "The Monolith Strikes Back" + Amazon Prime Video switching back to monolith (Prime Video saved costs going from serverless microservices back to EC2/ECS monolith) — both cited in glossary as "microservices are not always better" ## Bounded context (for sizing a microservice) A microservice should be scoped as a **bounded context** (Fowler) around a business entity (Book, Order, Cart, Bill, Payment, Notification). Operations within a context can be coupled; operations across contexts should be loosely coupled. ## CQRS (Command Query Responsibility Segregation) — optional scaling pattern If reads >> writes (e.g., browsing books vs adding books), split into separate read-microservice + write-microservice with separate DBs. Enables independent scaling at cost of temporary read/write inconsistency. ## ⚡ Al Hilal Bank (AHB) — the W11 case **Setup:** 2007 Abu Dhabi Islamic bank → 2019 acquired by ADCB → shifted to digital-only retail bank → launched "Al Hilal Digital" super-app Feb 2022. **Key decisions & why MSA helped:** - **Super-app business model** (banking + marketplace for food, shopping, travel) → modular microservices for each capability - **Cloud migration** (on-prem → public cloud, 85% done by June 2023) → microservices fit naturally with cloud scaling - **Squads** (cross-functional teams w/ daily huddles) → each squad owns a microservice → matches two-pizza rule - **Cut branch network** → UAE Pass + Emirates Face Recognition for digital onboarding (integration via APIs) - **DevOps + Agile** → 60 cloud releases in 9 months (was months-per-release under waterfall) - **12k new customers/month, 1M downloads, 140k accounts** within 12 months of app launch **Why microservices for AHB specifically:** - Faster feature delivery (independent deployments per squad) - Cloud-native scalability (containerize each service, scale hot ones like Customer, Account) - Partner integration via APIs (reselling insurance, flights, etc. through marketplace) - Legacy core banking systems integrated via **wrapper services** (Account is a wrapper over legacy) - Planned "Banking-as-a-Service" → expose APIs to 3rd parties (department stores offering store credit, etc.) **Four critical success factors (memorize):** 1. Organisational-wide change strategy (top-down leadership from CEO Shakeel) 2. Multi-sided platform (customers ↔ family ↔ UAE gov't identity services ↔ partners) 3. Cloud-based IT infrastructure 4. Rapid execution (Agile + Cloud = weeks, not years) **AHB SOA layers (from lecture):** - **UI**: Al Hilal Digital app - **Composite**: e.g., onboarding flow, family payment features - **Atomic**: Customer, Payment, Notification - **Wrapper**: Account (sits on legacy core banking) - **Legacy/IT Systems**: core banking ## ⚡ Strangler Fig Pattern (W11 — high exam probability) **Problem:** can't big-bang rewrite a mission-critical legacy system (cf. TSB bank IT meltdown). **Solution — metaphor**: a strangler fig seeds in upper branches of a host tree, gradually roots downward, eventually strangles & replaces the host. **Three phases:** 1. **Transform** — identify a capability of the monolith, build a new microservice replicating that capability 2. **Co-exist** — run both old and new; put a **façade** in front to intercept requests and gradually route them to the new service 3. **Eliminate** — once no other part relies on the old capability, decommission it (detect via instrumentation/monitoring) **Why it works:** incremental, rollback-safe, consumers don't need to know migration happened (façade preserves interface). --- # GROUP 3 — SOA Design, Atomic/Composite/Wrapper, Bookstore *Maps to: W2.1 · W2.2 · W7.1 · Mini Case 2 Bookstore · Labs 2+6* ## Service — definition **A unit that provides one or many functionalities needed to support business requirements and can be used by other applications/services over the network via a standard interface independent of programming languages and platforms.** - **Service Provider Interface (SPI)** — code at the provider end - **Service Consumer Interface (SCI)** — code at the consumer end A monolith's functionality becomes a *service* when it's exposed through a standard interface. ## Service vs Microservice — the key test A service is a **microservice** if it can be **independently developed and deployed**. Microservice = service + independence criteria from Group 2. ## ⚡ Atomic / Composite / Wrapper | Attribute | Atomic | Composite | Wrapper | |---|---|---|---| | **Independently deployable** | Yes | Yes | No (coupled to underlying system) | | **Independently scalable** | Yes | Yes | No (depends on underlying) | | **Encapsulates** | Single "atomic" entity (Customer, Book) | A process (Place Order, Make Payment) | Existing functionality of legacy/external system | | **Naming** | **Noun** (book, order) | **Verb** (Place Order, Process Shipping) | Often describes the wrapped system | | **Can invoke other services** | **Never** | **Yes — that's its purpose** | Usually just the wrapped system | | **Data ownership** | Exclusive owner of its tables | Doesn't own data, requests via APIs | Doesn't own — delegates to wrapped system | | **Implementation** | CRUD on one entity | Orchestrates/aggregates others via IPC | Function calls into legacy + service interface out | ## Composite Service vs Composite Microservice (⚡ exam trap) - A **composite service** can (a) directly invoke a monolith's function OR (b) run a long-running process with human intervention - A **composite microservice** cannot do (a) or (b) — it must be independently scalable - **Exception**: if the monolith is easily scalable (e.g., a DB behind standard connection URL, or a Google API), a composite service calling it *can* still be called a composite microservice ## Atomic Service "Independence" nuances - An atomic microservice can use a shared DB or HTTP server (because those are commonly-used, scalable infrastructure) - Should NOT invoke other microservices via HTTP (that makes it depend on their URLs) - Can still *send messages out* (e.g., publishing events via AMQP) — but messages shouldn't target a specific receiver - Can still *reply* when requested (HTTP response, AMQP reply) ## Wrapper service notes - Often implemented via function calls to the monolith (same language, same machine) → high coupling - Causes runtime slowdown (extra wrapping operations) — acceptable trade-off - **Main benefit**: standardization → easier CI/CD + easier replacement later (swap wrapper + monolith for a new microservice with same interface → minimal downtime) - Wrapper/Adapter/Connector/Plug-in: treated as synonyms in this course ## Bookstore Scenario (Mini Case 2) — standard reference solution **Entities**: Book, Order, Shipping Record, Activity Log, Error **Atomic microservices** (CRUD on one entity each): - `book` (GET all, GET by ISBN, POST new) - `order` (POST new, GET all, GET by id) - `shipping_record` - `activity_log` (often no DB — just logging) - `error` (often no DB — just printing in lab) **Composite microservices**: - `place_order` — orchestrates order creation + shipping record + activity log + error - `process_shipping_record` — updates shipping status + relevant order **UI**: Amazing Bookstore UI (customer view + warehouse operator view) ### "Not-so-good" solution vs Good solution (W2.2) - Bad: the Order atomic service orchestrates everything → it's no longer atomic, it's tightly coupled to business process - Good: separate `Place an Order` composite microservice orchestrates; Order stays atomic (just CRUD) - **Takeaway**: business logic belongs in composite, entities stay atomic ## API Documentation Document each REST endpoint: Resource · Method · URL · Description · Content-type · Input sample. **Swagger** = industry tool for auto-generating API docs. OutSystems auto-creates Swagger for REST APIs. ## Python/Flask REST template (exam-critical snippet) ```python from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy from flask_cors import CORS app = Flask(__name__) db = SQLAlchemy(app) CORS(app) @app.route("/book/<string:isbn13>") def find_by_isbn13(isbn13): # ... query logic return jsonify(result), 200 @app.route("/book", methods=['POST']) def create_book(): data = request.get_json() # ... create logic return jsonify(created), 201 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) ``` --- # GROUP 4 — REST, JSON, HTTP, Networking, Flask *Maps to: W1.4 · W1.5 · W4.1* ## REST (Representational State Transfer) Proposed by Roy Fielding (2000 PhD). An architectural style, not a strict protocol. **Uses standards**: HTTP · URL/URI · JSON/HTML/XML/JPEG · stateless **REST characteristics**: - Client-server - Uniform standardized interface (language & platform agnostic) - HTTP/HTTPS transport - Stateless (server doesn't remember previous calls — client sends full context each time) - Self-describing data - Layered (proxies, gateways, caches, load balancers in between allowed) ## HTTP methods (exam-critical) | Method | Intent | CRUD mapping | |---|---|---| | **POST** | Create | C | | **GET** | Retrieve | R | | **PUT** | Update | U | | **DELETE** | Delete | D | ## HTTP response status codes (practical subset) - 200 OK · 201 Created · 400 Bad Request · 404 Not Found · 500 Internal Server Error ## JSON essentials - Lightweight text-based data-interchange format - Self-describing, language-agnostic, human-readable - **Syntax rules**: - `{}` = object (unordered name-value pairs) - `[]` = array (ordered list) - Strings use **double quotes only** - Types: number, string, boolean (`true`/`false`), array, object, `null` - Name and value separated by `:` - Pairs separated by `,` - Python: `import json; json.loads(str)` / `json.dumps(obj)` / `flask.jsonify(obj)` ### JSON object example ```json { "books": [ {"availability": 2, "isbn13": "9781129474251", "price": 21.5, "title": "SQL in Nutshell"}, {"availability": 25, "isbn13": "9781349471231", "price": 99.4, "title": "Understanding People"} ] } ``` ## Networking basics | Concept | One-liner | |---|---| | **IP** (IPv4) | 4-byte address, e.g. `192.168.0.101`. Identifies a machine on a network. | | **Hostname** | Human-readable name, maps to IP via DNS | | **DNS** | Host-name registry (maps names ↔ IPs) | | **DHCP** | Dynamically assigns IPs to machines on a LAN | | **Gateway** | Device connecting a subnetwork to the wider network | | **Port** | Identifies a process on a machine (e.g., HTTP on 80, SMTP on 25) | | **localhost / 127.0.0.1** | Loopback — refers to current machine itself | | **Ping** | Test whether a host is reachable | | **Load balancer** | Distributes network traffic across multiple servers | | **Subnet / intranet / internal network** | Private network, often inaccessible from outside | ## NAT (Network Address Translation) — ⚡ tested concept **What**: maps one network address (IP+port) to another by modifying address info in communication data. Enables cross-network communication. **Use cases**: - Home router: internal 192.168.x.x ↔ external public IP - Docker engine: container internal IPs (172.17.x.x) ↔ host external IP via port forwarding **Port forwarding / port mapping** = a specific kind of NAT (redirect `host:5000` → `container:5000`). ## Internal vs External IP/Port (Glossary concept) - Each machine can belong to multiple networks, each with its own IP - A Docker container has **internal** IP in the Docker virtual subnetwork - The Docker host has an **external** IP in the physical network - External clients can't reach containers directly → NAT/port mapping on host relays --- # GROUP 5 — Docker, Image vs Container, Compose, YAML *Maps to: W4.1 · W4.2 · Labs 4, 10.1, 10.2, 11* ## Why Docker? The deployment problem Moving a microservice to another machine breaks because of: wrong Python version · missing modules · DB access fails · DB not running · firewall. Solution: **containerize** — package everything needed into an image. ## Docker — what it is An open platform to package, transfer, and run microservices (or any app) on any machine, on-premise or in the cloud. ## ⚡ Image vs Container | | Image | Container | |---|---|---| | **What** | File built by `docker build` (layers of software + data, snapshot) | Instance created by `docker run` from an image | | **Relationship** | 1 image → many containers (each with own state) | 1 container = 1 instance of exactly 1 image | | **Analogy** | Software program | Running process of that program | | **Name origin** | Disk image / optical disc image (NOT photo) | Shipping container (standardized cargo) | ## Dockerfile Text file containing build instructions. Key commands: `FROM`, `COPY`, `RUN`, `CMD`, `EXPOSE`, `ENV`, `WORKDIR`. ## Docker architecture — 3 major components 1. **Docker daemon / engine / server** — the service running on the host, manages images/containers/networks 2. **Docker client** — CLI that talks to the daemon (can be remote) 3. **Docker host** — the machine where daemon runs (has Docker installed) Each container is essentially a lightweight VM — but shares the host OS kernel (vs full VM which has its own OS → much less overhead). ## VM vs Container (Glossary) | | Virtual Machine | Docker Container | |---|---|---| | **Has own OS?** | Yes (virtual operating system) | No — shares host OS kernel | | **Overhead** | Heavy (boot an OS) | Light (just start a process) | | **Isolation** | Strong | Moderate (process-level) | | **Startup time** | Minutes | Seconds | ## Container networking (⚡ asked every year) - Each container gets an **internal IP** (typically `172.17.0.x`) in the virtual network created by Docker engine - Docker engine acts as the **gateway** for containers - **Same network (container → container)**: use container name as hostname, or internal IP - **Container → host**: use special hostname `host.docker.internal` (Win/macOS) or host's internal IP - **External client → container**: must go through the host via **port mapping** - e.g., `docker run -p 5000:5000 book` maps host's 5000 → container's 5000 ### Port mapping syntax ``` docker run -p <host_port>:<container_port> <image> ``` ## Drawbacks of containerization - Must install Docker on every machine; not compatible with all OSes - Images take storage; many unused containers = cruft - Networking among containers is more troublesome than plain machines - Data is transient by default — must use volumes or `docker commit` to persist - Need separate tools to manage many containers (Compose, Kubernetes) - Easier to ship malicious content undetected ## Docker Compose Tool for defining and running multi-container apps. Uses YAML config. **Workflow**: 1. Define a `Dockerfile` for each custom image 2. Define services in `docker-compose.yml` 3. Run `docker compose up` (builds + starts everything) ## YAML "YAML Ain't Markup Language" — human-readable config format. - Indentation matters (like Python) - `-` = list item - `key: value` = map entry - Superset of JSON ## Sample docker-compose.yml (exam-relevant fragments) ```yaml services: book: build: context: ./ dockerfile: Dockerfile image: eklum/book:1.0 container_name: book ports: - "5000:5000" environment: - dbURL=mysql+mysqlconnector://is213@host.docker.internal:3306/book restart: always networks: - bookstore-net depends_on: - dbms dbms: image: mysql:9.2.0 ports: - "3306:3306" networks: - bookstore-net volumes: - bookstore-volume:/var/lib/mysql networks: bookstore-net: driver: bridge volumes: bookstore-volume: ``` **What each block does**: - `services`: list of containers to manage - `build`: path + Dockerfile for custom image - `image`: tag for pre-built or built image - `ports`: `host:container` port mapping - `environment`: env vars for container - `depends_on`: startup order - `networks`: shared network among containers - `volumes`: persistent storage ## Scaling with Compose Run multiple instances of one service: ``` docker compose up -d book --scale book=2 ``` Or in YAML: `deploy: replicas: 2` --- # GROUP 6 — Inter-Process Communication (IPC) + HTTP *Maps to: W5.1 · W5.2 · W7.2 LGB · Lab 5* ## Why IPC matters for MSA Each microservice runs as a separate process, often on a different machine. They need to communicate constantly → IPC is the glue of MSA. ## ⚡ Communication patterns — 3 axes ### Axis 1: How many receivers? | Pattern | Meaning | Example | |---|---|---| | **One-to-one** | 1 sender → 1 receiver | Mail a letter | | **One-to-all** | 1 sender → all receivers | Public warning siren | | **One-to-many** / **one-to-selected** | 1 sender → selected subset | WhatsApp group | ### Axis 2: Does sender expect a reply? | Pattern | Meaning | Example | |---|---|---| | **Fire-and-forget (FF)** | No reply expected | Radio broadcast, anonymous letter | | **Request-reply (RR)** | Reply expected | Phone call, ordering a book | ### Axis 3: Sender & receiver online simultaneously? | Pattern | Meaning | Example | |---|---|---| | **Synchronous** | Both online at the same time | Phone call | | **Asynchronous** | Not — uses an intermediary | Email (via email server), voicemail | ## ⚡ Communication technologies | | Invocation-based | Message-based (Messaging) | |---|---|---| | **Data flow** | Point-to-point, directly | Through message broker/intermediary | | **Typically** | Synchronous | Asynchronous | | **Examples** | Function call, HTTP, gRPC | AMQP (RabbitMQ), JMS | | **One-to-many?** | Simulated (loop 1-to-1) | Native via broker | | **Receiver offline?** | Call fails | Broker stores message | | **Sender knows receiver?** | Yes (URL/address) | No (only knows broker + routing key) | | **Coupling** | Tighter | Looser | | **Maintenance** | None | Must maintain broker | ## ⚡ P1 vs P2 principles (LGB case — heavily tested) - **P1**: If user/process needs **immediate response** → use **invocation-based, synchronous** communication - Rationale: avoid perception of slowness/no reaction - Implication: tighter coupling (unless API gateway in middle) - **P2**: If user/process does **NOT need immediate response** (long-running or async interaction) → use **message-based, asynchronous** communication - Rationale: enables loose coupling - Implication: added complexity from broker ## Applying P1/P2 — scenario drills (from LGB Ex. 4) | Scenario | P1 or P2? | |---|---| | UI needs to display account balance | **P1** (user is waiting) | | Composite service needs account balance | **P1** (composite is waiting) | | UI triggers automated account creation + display result | **P1** | | Composite service sends notification to customer | **P2** (customer not waiting at that instant) | | UI triggers appointment booking with bank staff who may not be reachable | **P2** (long-running, needs human) | ## HTTP server-side (Flask) ```python from flask import Flask, request @app.route("/book/<string:isbn13>", methods=['POST']) def create_book(isbn13): if request.is_json: data = request.get_json() else: data = request.get_data() return isbn13, 200 ``` ## HTTP client-side (Python requests) ```python import requests r = requests.get("http://localhost:5000/book", timeout=1) print(r.status_code, r.text) # POST with JSON r = requests.post(url, json=bookinfo, timeout=1) # Or generic r = requests.request('POST', url, json=bookinfo, timeout=1) ``` ## Bookstore "Place an Order" — communication pattern breakdown Looking at the Place an Order composite microservice flow: - **UI ↔ Place an Order**: 1-to-1, sync RR (user waiting) - **Place an Order ↔ Order**: 1-to-1, sync RR (composite needs the order ID) - **Place an Order → Activity Log**: 1-to-1, fire-forget (no reply needed) - **Place an Order ↔ Shipping Record**: 1-to-1, sync RR (composite needs shipping outcome) - **If error → Error handler**: 1-to-1, FF - Combined fail case: **Place an Order → Activity Log + Error** = 1-to-two, FF Sensible tech choices: - UI ↔ Place Order, Place Order ↔ Order, Place Order ↔ Shipping Record: **HTTP** (P1) - Place Order → Activity Log, Error: **AMQP messaging** (P2 — no reply needed, enables 1-to-many) ## HTTP weakness that messaging fixes HTTP always returns a reply, even if empty → wasteful for fire-and-forget cases. Also harder for 1-to-many. Messaging is cleaner here. --- # GROUP 7 — Messaging, AMQP, RabbitMQ, Pika *Maps to: W5.3 · W5.4 · W7.2 LGB · Lab 5* ## MOM (Message-Oriented Middleware) Software between apps/microservices that lets them exchange data as messages. Overall architecture = **hub-and-spoke** (through a central broker) — contrast with peer-to-peer of HTTP. ## Common message structure (3 parts) 1. **Networking / transport info** (headers, protocol stuff) 2. **Properties / metadata** (key-value pairs: delivery_mode, correlation_id, reply_to) 3. **Body** (actual business data — often JSON) ## AMQP (Advanced Message Queuing Protocol) - Open standard protocol for MOM - Defines extensible message format - Interoperability across AMQP-compliant implementations - Supports all the comm patterns (1-1, 1-many, FF, RR) ### The AMQP stack in this course | Layer | Example | |---|---| | **Protocol** | AMQP | | **Broker software** | **RabbitMQ** (implements AMQP) | | **Python client library** | **pika** | ## ⚡ RabbitMQ core objects | Object | Role | |---|---| | **Producer / Publisher** | Sends messages | | **Consumer / Subscriber** | Receives messages | | **Broker** | Accepts, stores, forwards messages (the RabbitMQ server) | | **Queue** | Named message storage inside the broker (analogy: post box) | | **Exchange** | Routes messages to queue(s) based on routing/binding keys (analogy: postman) | | **Routing key** | Set by publisher on each message (e.g., `"order.info"`) | | **Binding key** | Set when binding a queue to an exchange; can be wildcard pattern | ## Routing logic 1. Publisher sends message **to an exchange** with a **routing key** 2. Exchange matches routing key against binding keys of queues bound to it 3. Message lands in matching queue(s) 4. Subscribers pull from queues they're consuming ## ⚡ Exchange types (exam-critical) | Exchange | Routing behavior | Best for | |---|---|---| | **Direct** | Queue receives if binding key == routing key exactly | **One-to-one** (email → inbox, home mailbox) | | **Fanout** | Routes to **ALL** queues bound to it (ignores routing key) | **One-to-all** (radio broadcast, group email, news subscription) | | **Topic** | Wildcard pattern match (routing key vs binding key) | **One-to-selected** (Facebook notification types) | ### Topic wildcards - `*` matches exactly **one word** - `#` matches **zero, one, or many words** - Words separated by `.` - Examples: - `*.error` matches `order.error`, `shipping.error`, but NOT `system.fatal.error` - `#.info` matches `info`, `order.info`, `more.order.info` - `#` matches ANY key - `order.*` matches `order.info`, `order.error`; NOT `order.urgent.error` ### Which exchange for which pattern? | Communication pattern | Most natural exchange | |---|---| | One-to-one | Direct | | One-to-all | Fanout | | One-to-selected-many | Topic | | FF / RR | Any (RR = two one-way messages) | *Topic can emulate direct or fanout too — it's the most general type.* ## ⚡ Load balancing via queues If **multiple consumers subscribe to the SAME queue**, messages are distributed round-robin (or random) across them → the queue acts as a load balancer. This is how you horizontally scale a receiver without any extra infra. ## Durability & persistence (glossary terms to know) - **Durable queue/exchange**: survives broker reboot - **Persistent message**: `delivery_mode=2` (pika.spec.PERSISTENT_DELIVERY_MODE) — survives broker reboot while on queue - **Transient message**: `delivery_mode=1` — dropped if no subscriber when it arrives or broker reboots - **TTL** (time-to-live): how long the message stays alive before expiring ## ⚡ Pika programming model ### Publisher ```python # 1. Connect connection = pika.BlockingConnection(...) # 2. Channel (virtual session) channel = connection.channel() # 3. Declare exchange channel.exchange_declare(exchange='order_topic', exchange_type='topic', durable=True) # 4. Publish channel.basic_publish( exchange='order_topic', routing_key='order.info', body=json.dumps(order), properties=pika.BasicProperties(delivery_mode=2) # persistent ) # 5. Close connection.close() ``` ### Subscriber ```python # 1. Connect + channel connection = pika.BlockingConnection(...) channel = connection.channel() # 2. Declare exchange + queue channel.exchange_declare(exchange='order_topic', exchange_type='topic', durable=True) channel.queue_declare(queue='Activity_Log', durable=True) # 3. Bind queue to exchange channel.queue_bind(exchange='order_topic', queue='Activity_Log', routing_key='#') # receive everything # 4. Consume def callback(channel, method, properties, body): # process message print(body) channel.basic_consume(queue='Activity_Log', on_message_callback=callback, auto_ack=True) channel.start_consuming() # Ctrl+C to stop ``` ### ⚡ Role discipline (likely exam point) - **Publishers** declare exchanges + set routing keys; do NOT declare queues; do NOT know subscribers - **Subscribers** declare queues + bind them with binding keys; do NOT know publishers ## Scenario: Bookstore Place-an-Order with AMQP Replace HTTP for FF parts with AMQP: - `Place an Order` publishes to topic exchange `order_topic` - routing key `order.info` on success → goes to `Activity_Log` queue (binding `#`) - routing key `order.error` / `shipping.error` on failure → goes to `Error` queue (binding `*.error`) AND `Activity_Log` (binding `#`) Result: one message can fan out to multiple consumers without the sender knowing them. --- # GROUP 8 — API Gateway, Kong, myTaxi *Maps to: W10.1 · W10.2 · W10.3 · Mini Case 3 · Labs 10.2, 11* ## The problem API Gateway solves When many microservices and many clients exist, clients end up knowing too many URLs/routing keys. A URL change breaks every client. Clients also duplicate logic for auth, monitoring, load balancing, caching. ## API Gateway — definition A middleware (often a software component) that **manages external access** to microservices. Usually exposes services as REST APIs since REST is the most-used by clients. **Mental model**: the API Gateway is to HTTP what the Message Broker is to AMQP — a central intermediary that decouples senders and receivers. ## ⚡ 7 functionalities of an API Gateway (exam — memorize) | # | Functionality | What it does | |---|---|---| | 1 | **Routing (URL mapping)** | Maps client request URL → internal service URL. Client uses 1 stable URL; backend URLs can change freely | | 2 | **Load balancing** | Distributes requests across multiple instances of a service | | 3 | **Security enforcement** | Authentication, authorization, access control (API keys, ACLs, JWT) | | 4 | **Monitoring / logging** | Central log of all requests/responses, usage stats | | 5 | **Caching** | Stores responses for repeated requests, solution-wide benefit | | 6 | **Versioning** | Routes v1 clients to v1 services, v2 to v2, even transforms between them — enables incremental upgrades | | 7 | **Aggregation** | Combines responses from multiple services into one (for simple union/concatenation) | ## ⚡ Drawbacks of API Gateway - **Single point of failure** — its failure brings down everything - **Performance bottleneck** — extra hop adds latency; must be highly scalable itself - **Another component** to develop, deploy, manage ## myTaxi case — each exercise's point The myTaxi mini case walks through 7 needs (one per exercise) + summary. For each need, 3 options are compared: - **Option 1**: in each client (client-side) - **Option 2**: in each microservice (service-side) - **Option 3**: in an API Gateway (central) **Pattern of the answer**: option 1 is insecure (client code can be tampered) + inefficient (duplicated everywhere) + requires config file updates across all clients; option 2 centralizes per-service but creates duplicate code across services; **option 3 (gateway)** decouples cross-cutting concerns from business logic, centralizing them. ### ⚡ Summary from Ex.8 Issues without a gateway: URL coupling, client-side complexity, duplicated auth/logging/caching, hard to enforce policies, hard to version, hard to expose as open APIs. With a gateway: routing · load balancing · security · monitoring · caching · versioning · aggregation (the 7 above). Drawbacks: SPOF · performance overhead · additional component. ## Open APIs (from myTaxi + Al Hilal) - **Open API** = public API (usually REST) giving programmatic access to 3rd-party apps - Enable new business opportunities: `myMap`, `myHotel`, `myHandyman` integrating myTaxi booking - Revenue model: pay 10% commission to partners per booking made via their app - **Why gateway is almost required**: routing per partner + monitoring to track who booked what + access control via partner-specific API keys + billing attribution ## Kong — the gateway used in labs Open-source API gateway. Runs in a Docker container. ### Kong concepts (memorize for lab questions) | Kong object | Meaning | |---|---| | **Service (Kong service)** | Abstract representation of an upstream microservice (stores its URL) | | **Route** | Maps client-facing URL path to the Kong service (like `@app.route` in Flask) | | **Upstream** | Virtual hostname referencing multiple **targets** for load balancing | | **Target** | Actual host of a running microservice instance (e.g., `book1:5000`) | | **Consumer** | Account representing a client/user | | **Consumer group** | Group of consumers | | **API key** | Credential for a consumer | | **ACL** | Which consumer groups can access which services/routes | | **Plugin** | Adds features (auth, rate-limit, Prometheus metrics, etc.) | ### Kong ports (lab-memory) - **8000** — HTTP request entry (where clients send requests) - **8001** — admin API (RESTful config of Kong) - **8002** — Kong Manager GUI (web admin UI) ### Kong load balancing setup 1. Create an **upstream** (virtual hostname) 2. Add multiple **targets** (e.g., `book1:5000`, `book2:5000`) 3. Change the **service's** host to point to the upstream (instead of a target) 4. Kong distributes requests across targets ### Kong + Docker Compose for replicas Can also scale via `docker compose up -d book --scale book=2`, or put `deploy: replicas: 2` in YAML. ### Kong monitoring stack - Kong **Prometheus plugin** exposes metrics on port **9090** - **Prometheus** server scrapes and stores time-series data - **Grafana** (port 3000) connects to Prometheus for visualization dashboards - For AHB: this is the "BTL extension" pattern — also used in BloodLink --- # GROUP 9 — SOA Layers, LGB Case, Al Hilal (revisit), P1/P2, Strangler Fig *Maps to: W2.1 · W7.1 · W7.2 · W11 · Labs 7, 10.1* ## ⚡ SOA vs MSA (big picture) | | SOA | MSA | |---|---|---| | **Service size** | Any — small or big monolithic | Small, independently deployable | | **Includes monoliths?** | Yes, wrapped | Discouraged (only via wrappers) | | **Tech stack** | Often shared (ESB, SOAP) | Polyglot (REST, messaging) | | **Dev teams** | Often centralized | Small autonomous squads | | **Principle** | Services with standard interfaces | Services with standard interfaces + strict independence | If an SOA has only small independently-deployable services with standard interfaces, it IS an MSA. ## ⚡ Sample SOA layers (the standard diagram) From top (user) to bottom (data): 1. **User Interface Layer** — screens, apps - Triggers processes; can invoke service layers (not monoliths) 2. **Business Process / Composite Layer(s)** - Straight-through composites (automated flows like "Place an Order") - Long-running composites (involve human steps, e.g., loan approval) 3. **Atomic Microservice Layer** - Independently scalable, one-entity-focused - Do NOT communicate with other atomic services directly 4. **Wrapper Service Layer** - Expose legacy/external/monolith functionality as services 5. **IT Systems Layer** - COTS, custom, legacy apps. Do NOT communicate with other layers directly 6. **External Services Layer** - 3rd-party services (Google, Stripe), may or may not be microservices **Cross-cutting infrastructure**: API Gateway · Enterprise Service Bus (ESB) · Business Process Management · Message Broker · Container Management ### The rules to remember - Higher layers reuse lower layers' functionality - UI **never** talks to IT Systems directly — only via services - Atomic microservices **never** call other atomic services (that's the composite's job) - IT Systems **never** talk directly to UI/composites — only via wrappers ## ⚡ LGB Bank Case — "Issue Insurance Policy" (most likely exam case) ### Setup LGB Bank is a reseller of Travel Insurance from INSCO. Previously 3-day batch processing. Choice: new monolith OR compose existing microservices. Chose composite microservices. ### LGB's existing atomic microservices (memorize) - **Deposit Account** (CRUD + publish Deposit Event) - **Card Account** (CRUD + Card Event) - **Insurance Account** (CRUD only) - **Limit** (Get/Update + Limit Event) - **Fee** (Get/Update) - **Exchange Rate** (Get only) - **Loyalty Points** (Add/Get/Redeem + Loyalty Event) - **Journal Entry** (subscribes to all events, creates journal entries) - **Notification** (subscribes to events needing customer alerts, sends SMS/Email) ### INSCO atomic microservices (external — wrapper-like) - **Insurance Plan** (Get plans) — marketing details, no pricing - **Insurance Premium** (Calculate) — given plan + payment option → premium amount - **Insurance Proposal** (Create) — given plan + premium → proposal ID - **Insurance Policy** (Create) — given proposal + customer → policy ID ### The 5-step Issue Travel Insurance flow 1. **Get Insurance Plans** — UI → INSCO (direct) — **P1** (user browsing) 2. **Calculate Insurance Premium** — UI → INSCO — **P1** (user waiting) 3. **Get Payment Methods** — UI → composite **aggregates** Deposit + Card + Loyalty — **P1** (user about to pay) 4. **Create Insurance Proposal** — UI → INSCO — **P1** (user waiting for proposal to review) 5. **Issue Insurance Policy** — UI → composite **orchestrates**: 1. Create Insurance Account 2. Make Payment (another composite — orchestrates Deposit, Card, Fee, Exchange, Loyalty via sync HTTP; publishes Payment Event to Journal + Notification via async AMQP) 3. Create Insurance Policy (INSCO) 4. Update Insurance Account with policy ID 5. Publish Policy Event (to Journal + Notification via AMQP) — **P1** for user-waiting parts, **P2** for Journal/Notification (user doesn't need to wait for an SMS) ### Pattern: Aggregation vs Orchestration - **Get Payment Methods** = **Aggregation** (parallel calls, combine responses, return to caller) - **Issue Insurance Policy** = **Orchestration** (ordered steps, each may depend on previous, may involve rollback logic) - **Make Payment** = nested composite microservice (composite calls composite) — reusable for any payment process ### Conclusion of LGB case - No new atomic microservices needed — pure composition - New composites reusable: Get Payment Methods → Grab Pay; Make Payment → any fund transfer; Issue Insurance Policy → any insurance type - 3-day batch → near real-time via composite orchestration ## ⚡ Orchestration vs Choreography | | Orchestration | Choreography | |---|---|---| | **Control** | Central controller (composite service) dictates sequence | No controller — each service reacts to events | | **Suitable when** | Sequential / specific order, need consolidated results | Order is uncertain, no single consolidation point needed | | **Rollback** | Easier (controller knows what happened) | Harder (distributed state) | | **Typical tech** | Invocation-based (HTTP, RPC) | Message-based (AMQP, events) | | **Coupling** | Tighter (controller knows all participants) | Looser (emit event, receivers subscribe) | | **Failure handling** | Fail fast, central decision | Eventual consistency | | **Analogy** | Conductor directs orchestra | Dancers follow cues from each other | *Technically you can implement choreography with HTTP and orchestration with messaging — the choice is about coupling, not just tech.* ## Implementation steps for any business process in MSA (checklist for case study questions) 1. **Define the business process** (what activities, what triggers, what outcomes) 2. **Identify services** — atomic, wrapper, composite - Reuse existing? Or develop new? 3. **Compose interactions**: - Pick **communication patterns** (1-1 vs 1-many; FF vs RR; sync vs async) - Pick **technologies** (apply P1/P2 — HTTP for immediate-response, AMQP for async) - Pick **composition style** (orchestration vs choreography) 4. **Layer the architecture** (do we need a UI layer? Which composites belong in the process layer?) 5. **Supporting tools** (API gateway? Docker? Message broker?) --- # GROUP 10 — OutSystems (LCAP) *Maps to: W3.1 · W3.2 · W3.3 · Labs 3, 7* ## LCAP (Low Code Application Platforms) — attributes - Develop commercial-grade, full-stack apps with low/no coding - GUI Designer Studio — drag-n-drop + configure - One-click publish to cloud runtime - Fully managed Dev/Test/Prod by LCAP provider - Very expensive enterprise licensing — governments, banks, telcos - In Singapore: all gov agencies use LCAP for new apps; SingTel/StarHub adopting; SMU IT builds internal apps with LCAP; SMU has OutSystems spinoff Narfin ## Gartner: OutSystems in Leader Quadrant for LCAP for years. ## ⚡ Low Code vs Traditional Coding (exam table) | | Traditional Coding | Low Code (OutSystems) | |---|---|---| | **Licensing cost** | Low/none (open source, some DB licenses) | High (>$1M/yr for large orgs) | | **Infrastructure cost** | High (AWS for Dev/Test/Prod, API gateway, etc.) | None (managed) | | **Developers needed** | High | ~1/3 the number | | **Infra/DB engineers** | At least 2 per hosted app | None | | **Code repo, version ctrl, CI/CD** | GitHub | Built in | | **Packaging & deployment** | Docker, Kubernetes | 1-click publish | | **Full stack** | Yes | Yes | | **Standards (JSON/REST, OAuth)** | Yes | Yes | | **Speed of development** | Baseline | ~3× faster | | **Ease of maintenance** | Baseline | Easy (logic is visual) | ## Software Engineering principles still apply in LCAP - **Separation of Concerns** — frontend/backend split, REST/Swagger as "service contract" - **Encapsulation** — group related logic in "service boundaries" - **Reuse** — design services as reusable building blocks - **SOA Layered Architecture** still applies (UI · Composite · Atomic · Wrapper) ## OutSystems Designer Studio — 4 layers ### Data Layer - **Database Entities** — auto ER diagrams, auto CRUD, auto DB (MSSQL by default). Bootstrap from Excel - **Static Entities** — read-only, developer-setup, for enumerations (role types, document types) - **Structures** — developer-defined data types; for REST APIs, Structure = JSON object; List of Structures = JSON array. **Attribute names are case-sensitive** (must match `Name in JSON` config) - **Client Variables** — browser-side memory, not persisted at server; only primitive types; Structures must be serialized (JSON → Text) before storing - **Site Properties** — server-side, application scope, global params, changeable at runtime via Service Center (no republish needed) - **Resources** — static files (favicon, custom JS/CSS, Excel bootstraps) ### Logic Layer - Client-side logic runs in browser (emits React.JS) - Server-side logic runs on server (emits C# .NET) - Expose/consume REST APIs (Swagger auto-generated) **Built-in Client Widgets (for UI screens)**: - Message, Run Client Action, Run Server Action, Refresh Data, If, Switch, For Each, Assign, JSON Serialize, JSON Deserialize, Exception Handler, Raise Exception, Destination, Download, JavaScript **Built-in Server Widgets**: - Run Server Action, Aggregate (SELECT on Entity → List), SQL (any SQL), If, Switch, For Each, Assign, Record List to Excel, Excel to Record List, JSON Serialize/Deserialize, Exception Handler, Raise Exception, Comment, Send Email (use SMULab wrapper instead) **For Each attributes** (when iterating a List): - `Current` — current iteration value - `CurrentRowNumber` — index - `Length` — total items - `BOF` / `EOF` — at beginning / past end (booleans) - `Empty` — true if list is empty **List actions**: ListAll, ListAny, ListAppend, ListAppendAll, ListClear, ListDistinct, ListDuplicate, ListFilter, ListIndexOf, ListInsert, ListRemove, ListSort **User Functions**: any Client Action can be marked as `Function = Yes` to make it callable via the Expression Editor. ### Interface Layer - Deployment options: Reactive Web App, PWA Mobile - Layout templates: Side Menu, Top Menu, etc. - Drag-n-drop: Dropdowns, Buttons, Checkboxes, Radio Buttons, Inputs, Tables - Event handlers: OnClick, OnFocus, OnBlur, OnKeyUp, OnKeyDown - Client Actions run browser-side logic ### Processes Layer - Orchestrate/subscribe to messaging, e.g., RabbitMQ (ConsumeMessage every 100ms) - Handle exceptions via Exception Handler chain ## OutSystems can do everything for ESD scope - ✅ Develop data models / host databases (MSSQL by default) - ✅ Expose REST APIs (auto Swagger docs) - ✅ Consume REST APIs - ✅ Develop UIs (web + PWA mobile) - ✅ Develop business logic (visual) - ✅ Subscribe to RabbitMQ ## OutSystems Forge (plugins) Downloadable components: OpenAI, Google Maps, WhatsApp, Stripe, Speech Recognition, Bitcoin, Coinbase. ## SMULab Utilities (wrapper services for student projects) Pre-built wrapper services — e.g., for storing content/images. Some require API keys registered per project team. ## Who uses OutSystems at SMU? - SMU IT: internal apps (Purchase Order System, Facilities Booking, COI Declaration, PGP Admissions) - SMU FYP students: banking apps (IB, Corporate IB, etc.) - Narfin (SMU spinoff): Treasury Management, FX Hedging, Digital Client Onboarding with Singpass + facial recognition + CDD --- # APPENDIX A — Glossary of "X vs Y" distinctions (catchall) ## IT System vs Application vs Enterprise System vs Business App All synonyms for this course. In practice: - Systems > applications (systems include hardware) - Enterprise > business (enterprise = the whole org) ## Software vs Application vs Program All synonyms for this course. In practice: - Software = broadest (any computer programs) - Application = user-focused software (Windows itself isn't an app) - Program = specific instructions (developers' term) ## Solution vs Application - Application = specific functionality - Solution = holistic — design, impl, deployment, maintenance, hardware, software, processes ## Service vs Web Service vs REST Service - REST service = web service using HTTP + flexible data formats + stateless - Web service = service accessible over web/network (not necessarily internet — could be internal) - REST services = REST APIs (synonyms) ## Service vs API - API = very broad; any invocable interface (Python module APIs are APIs but not services) - Service = standardized API over a network, language/platform-agnostic - Treated as synonyms in this course ## Service vs Interface - "Interface" is overloaded — UI, function interface, API - Service = standardized API - Service can refer to interface + implementation; interface is just interface ## Data Exchange / Transfer / Transmission / Communication / Transport All synonyms in this course. In practice: - Exchange = possibly among multiple parties - Transfer/Transmission = one-way - Transport = also method/technique - Communication = meaningful exchange w/ mutual understanding ## Data Format vs Data Model Synonyms in course. Format = computer representation (JSON, HTML); model = concepts+meanings in business context. A model must be expressed in some format. ## Data Transformation / Translation / Formatting / Changes Synonyms in course. Translation = language/medium/format change; transformation = big change; formatting = syntactic/small; changes = colloquial. ## Internet / Network / Intranet / Extranet - Internet = big public network (WWW) - Intranet = internal private org network - Extranet = org-owned but accessible to external authorized users (vendors, partners) - External network = everything NOT owned by the org (≠ extranet) - Subnetwork = logical division of a network ## Virtual Network vs Network Virtual network = software-driven, built on physical networks. VPN is example. ## Machine vs Host - Machine = physical computer - Host = any system that runs/hosts something (can be virtual) - Local host = machine you're using - Remote host = server machine you're not physically at ## Microservice vs Database - Each microservice should have its own **database** (not necessarily own DBMS) - Multiple microservice DBs can live in one DBMS as long as each has exclusive ownership of its tables - **Polyglot persistence** — use different DB types for different microservices (geo-spatial DB for location service, ElasticSearch for search service, etc.) ## Database / Schema / Table / DBMS / Data Store - DB = organized collection of data (tables + schemas + data) - Schema = structure/blueprint (DB schema, table schema, JSON schema, etc.) - Table = schema + stored data - DBMS = software that manages DBs (e.g., MySQL) - Data Store = generic term for any data storage --- # APPENDIX B — ⚡ SCENARIO QUICK-DRAW CHEATSHEET When you see these prompts, trigger these answers: | Prompt says... | Answer with... | |---|---| | "User is waiting for a response" | **P1** → sync HTTP invocation | | "Long-running / no immediate response needed" | **P2** → async AMQP messaging | | "Send notification/log (user not waiting)" | **P2** → AMQP FF | | "Receiver might be offline" | AMQP (broker stores message) | | "Multiple receivers of same message" | AMQP fanout or topic | | "One-to-one request-reply" | Direct exchange (or HTTP) | | "One-to-all broadcast" | Fanout exchange | | "One-to-selected-many" | Topic exchange | | "Load balance multiple receivers" | Multiple consumers on same AMQP queue (round-robin) OR API Gateway load balancing across HTTP instances | | "Legacy system, hard to change, can't deploy independently" | **Wrapper service** | | "Orchestrates multiple services for a business process" | **Composite microservice** (verb name) | | "CRUD on one data entity" | **Atomic microservice** (noun name) | | "Client needs to know many URLs" | **API Gateway** for routing | | "Need auth/logging/rate-limiting for many services" | **API Gateway** (cross-cutting concerns) | | "Multiple versions of clients in the wild" | API Gateway **versioning** | | "Big-bang rewrite of legacy is too risky" | **Strangler Fig pattern** | | "Co-exist old + new during migration" | Strangler Fig: build façade → co-exist → eliminate | | "Too many container URLs to remember / manage" | **Docker Compose + API Gateway** | | "Container can't be reached from outside" | **Port mapping** (`-p host:container`) | | "Container needs to reach the host machine" | `host.docker.internal` hostname | | "Team small enough to be fed by two pizzas" | That's the **microservice sizing heuristic** | | "Independent scaling needed" | Microservice (monolith can't) | | "Quickly scale one hot function" | Multiple instances of that microservice + load balancer (Kong upstream / queue-based) | | "Sequential process with rollback" | **Orchestration** | | "Event-driven, unknown order" | **Choreography** | | "Aggregate data from multiple services" | Composite microservice (aggregation pattern) OR API Gateway aggregation | | "Expose service to 3rd parties with billing/tracking" | **API Gateway with Open APIs** | --- # APPENDIX C — Quick command & code reference ## Flask minimal REST ```python from flask import Flask, request, jsonify from flask_sqlalchemy import SQLAlchemy from flask_cors import CORS app = Flask(__name__) db = SQLAlchemy(app) CORS(app) @app.route("/resource/<string:id>") def get_one(id): return jsonify({...}), 200 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000, debug=True) ``` ## Python requests client ```python import requests r = requests.get(url, timeout=1) r = requests.post(url, json=data, timeout=1) r = requests.request('POST', url, json=data, timeout=1) print(r.status_code, r.text) ``` ## Pika publisher ```python channel.exchange_declare(exchange='X', exchange_type='topic', durable=True) channel.basic_publish(exchange='X', routing_key='a.b', body=json.dumps(data), properties=pika.BasicProperties(delivery_mode=2)) ``` ## Pika subscriber ```python channel.queue_declare(queue='Q', durable=True) channel.queue_bind(exchange='X', queue='Q', routing_key='a.*') channel.basic_consume(queue='Q', on_message_callback=cb, auto_ack=True) channel.start_consuming() ``` ## Docker commands ```bash docker build -t myimage:1.0 . docker run -p 5000:5000 -e dbURL=... myimage:1.0 docker ps docker stop <container_id> docker rm <container_id> docker compose up -d docker compose up -d book --scale book=3 docker compose down ``` ## HTTP methods mnemonic **P**OST = Put-new (Create) · **G**ET = Get (Read) · **P**UT = Put-change (Update) · **D**ELETE = (Delete) ## Topic exchange wildcards `*` = exactly one word · `#` = zero, one, or many words · words separated by `.` --- # APPENDIX D — Final Exam Strategy ## Question patterns to expect 1. **"What is X?"** → definition questions. Short, precise. Use the exact definition from the Glossary. 2. **"X vs Y"** → table-style comparison. Pick 3–5 distinguishing dimensions. 3. **"Given this scenario, design/improve the architecture"** → apply the Implementation Steps Checklist (Group 9). 4. **"What communication pattern/tech/exchange/etc. fits?"** → use the Scenario Cheatsheet (Appendix B). 5. **"Pros and cons of option A vs B"** → follow myTaxi case framing (client vs service vs gateway). 6. **Case-study application** (AHB, LGB, myTaxi, Bookstore) → identify service types (atomic/composite/wrapper), apply P1/P2, layer the architecture, discuss Strangler Fig if legacy migration. ## Common traps - Calling a composite service "atomic" because it's small - Forgetting that **atomic services don't call other services** — only composite do - Saying "API Gateway" when the problem is purely internal service-to-service (ESB or message broker fits there) - Using HTTP for one-to-many (awkward — messaging is better) - Confusing P1 and P2 — always ask "is the user/process waiting right now?" - Calling an atomic service a microservice even if it's tightly coupled to a legacy system — that's a wrapper - Saying "Docker container" when asked for "Docker image" — image is the file, container is the running instance ## Night-before checklist - [ ] Atomic/Composite/Wrapper table (memorize) - [ ] P1/P2 trigger words (memorize) - [ ] Exchange types + wildcard rules (memorize `*` and `#`) - [ ] SOA layer order (UI → Composite → Atomic → Wrapper → IT Systems) - [ ] 7 gateway functionalities + 3 drawbacks - [ ] Strangler Fig 3 phases (Transform → Co-exist → Eliminate) - [ ] LGB 5-step flow and where P1/P2 apply - [ ] AHB 4 critical success factors - [ ] Docker image vs container distinction - [ ] Microservice "independence" checklist (5 items) Good luck.