Skip to content

Latest commit

Β 

History

13 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🏭 Procurement Data Pipeline

Docker Hadoop Presto Airflow PostgreSQL

Big Data project for centralized procurement using Hadoop, Presto, and Apache Airflow

A production-ready data pipeline that processes Point-of-Sale (POS) orders and warehouse stock data to generate optimized supplier orders. Built with Hadoop HDFS for distributed storage, Presto for federated queries, PostgreSQL for master data, and Apache Airflow for orchestration.


πŸ“‹ Table of Contents


✨ Features

  • πŸ”„ Centralized Procurement: Single replenishment rule per SKU across all warehouses
  • πŸ“Š Big Data Storage: HDFS-based data lake for scalable storage
  • πŸš€ Federated Queries: Presto joins HDFS data with PostgreSQL master data
  • ⏰ Batch Orchestration: Apache Airflow DAG scheduling (daily at 22:00)
  • βœ… Data Quality: Automated validation checks (supplier mapping, demand spikes, duplicates)
  • πŸ“ˆ Exception Logging: Comprehensive fault tracking and reporting
  • 🐳 Fully Dockerized: One-command deployment with 9 containerized services
  • πŸ“ Historical Audit: Date-partitioned data preservation

πŸ— Architecture

System Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        DATA SOURCES                                  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  POS Systems    β”‚  Warehouse Stock  β”‚  PostgreSQL Master Data      β”‚
β”‚  (5 stores)     β”‚  (3 warehouses)   β”‚  β€’ Products (100 SKUs)       β”‚
β”‚  Daily Orders   β”‚  Daily Snapshots  β”‚  β€’ Suppliers (10)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                  β”‚                      β”‚
         β–Ό                  β–Ό                      β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     STORAGE LAYER                                    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  HDFS Data Lake                β”‚  PostgreSQL OLTP                   β”‚
β”‚  β€’ /raw/orders/YYYY-MM-DD/    β”‚  β€’ products                        β”‚
β”‚  β€’ /raw/stock/YYYY-MM-DD/     β”‚  β€’ suppliers                       β”‚
β”‚  β€’ /processed/                 β”‚  β€’ warehouses                      β”‚
β”‚  β€’ /output/                    β”‚  β€’ replenishment_rules             β”‚
β”‚  β€’ /logs/                      β”‚  β€’ supplier_products               β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚                                    β”‚
             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    QUERY ENGINE                                      β”‚
β”‚  Presto (Distributed SQL)                                            β”‚
β”‚  β€’ Hive Connector β†’ HDFS                                             β”‚
β”‚  β€’ PostgreSQL Connector β†’ Master Data                                β”‚
β”‚  β€’ Federated JOIN across data sources                                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 ORCHESTRATION LAYER                                  β”‚
β”‚  Apache Airflow                                                      β”‚
β”‚  β€’ Scheduled DAG (daily 22:00)                                       β”‚
β”‚  β€’ 6 Task Pipeline                                                   β”‚
β”‚  β€’ Retries & Alerts                                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      OUTPUT                                          β”‚
β”‚  Supplier Orders (CSV)                                               β”‚
β”‚  β€’ /data/output/supplier_orders/                                     β”‚
β”‚  β€’ HDFS: /procurement/output/supplier_orders/                        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Docker Services (9 containers)

Service Container Port Description
PostgreSQL procurement_postgres 5433 Master data (products, suppliers, rules)
HDFS NameNode namenode 9870, 9000 HDFS metadata & coordination
HDFS DataNode datanode - HDFS block storage
HDFS Client hadoop_client - CLI access with volume mounts
Presto presto 8080 Distributed SQL query engine
Airflow DB airflow_postgres 5434 Airflow metadata storage
Airflow Webserver airflow_webserver 8081 Web UI (admin/admin)
Airflow Scheduler airflow_scheduler - Task scheduling & execution
Airflow Init airflow_init - One-time DB setup (exits)

πŸ›  Technologies

Storage & Processing

  • Hadoop HDFS 3.2.1 - Distributed file system for raw/processed data
  • Presto - Federated SQL query engine (Hive + PostgreSQL connectors)
  • PostgreSQL 15 - OLTP database for master data
  • PostgreSQL 13 - Airflow metadata storage

Orchestration & Monitoring

  • Apache Airflow 2.x - Workflow orchestration with Web UI
  • Docker Compose - Multi-container deployment

Development

  • Python 3.9+ - Data generation, pipeline scripts
  • psycopg2 - PostgreSQL adapter
  • hdfs dfs - Hadoop CLI commands

πŸ“ Project Structure

procurement-pipeline/
β”œβ”€β”€ πŸ“‚ airflow/                          # Apache Airflow orchestration
β”‚   β”œβ”€β”€ dags/
β”‚   β”‚   └── procurement_pipeline_dag.py  # Main DAG (7 tasks, daily @ 22:00)
β”‚   β”œβ”€β”€ logs/                            # Task execution logs
β”‚   └── plugins/                         # Custom Airflow plugins
β”‚
β”œβ”€β”€ πŸ“‚ scripts/                          # Utility scripts
β”‚   β”œβ”€β”€ data_generation/                 # Test data generators
β”‚   β”‚   β”œβ”€β”€ generate_all_data.py         # Master script (--date param)
β”‚   β”‚   β”œβ”€β”€ generate_suppliers.py        # 10 suppliers
β”‚   β”‚   β”œβ”€β”€ generate_products.py         # 100 products
β”‚   β”‚   β”œβ”€β”€ generate_warehouses.py       # 3 warehouses
β”‚   β”‚   β”œβ”€β”€ generate_orders.py           # POS orders (5 stores)
β”‚   β”‚   β”œβ”€β”€ generate_stock.py            # Warehouse stock snapshots
β”‚   β”‚   └── generate_replenishment_rules.py  # 100 centralized rules
β”‚   β”œβ”€β”€ upload_to_hdfs.py                # HDFS upload automation
β”‚   β”œβ”€β”€ analyze_data.py                  # Data overview & testing tool
β”‚   β”œβ”€β”€ setup_hdfs.sh                    # HDFS directory initialization
β”‚   └── setup_hdfs.ps1                   # Windows version
β”‚
β”œβ”€β”€ πŸ“‚ docker/                           # Docker infrastructure
β”‚   β”œβ”€β”€ docker-compose.yml               # All 9 services in one file
β”‚   └── presto/
β”‚       └── catalog/
β”‚           β”œβ”€β”€ hive.properties          # HDFS connector config
β”‚           └── postgresql.properties    # PostgreSQL connector config
β”‚
β”œβ”€β”€ πŸ“‚ database/                         # Database schemas
β”‚   β”œβ”€β”€ schema.sql                       # PostgreSQL tables DDL
β”‚   └── db_connection.py                 # Connection utilities
β”‚
β”œβ”€β”€ πŸ“‚ config/                           # Configuration
β”‚   β”œβ”€β”€ config.py                        # Database & HDFS configs
β”‚   └── .env.example                     # Environment variables template
β”‚
β”œβ”€β”€ πŸ“‚ data/                             # Local data directory (gitignored)
β”‚   β”œβ”€β”€ raw/
β”‚   β”‚   β”œβ”€β”€ orders/YYYY-MM-DD/           # POS order JSONL files
β”‚   β”‚   └── stock/YYYY-MM-DD/            # Stock snapshot JSONL files
β”‚   β”œβ”€β”€ processed/                       # Intermediate results
β”‚   β”œβ”€β”€ output/
β”‚   β”‚   └── supplier_orders/             # Final CSV outputs
β”‚   └── logs/                            # Pipeline execution logs
β”‚
β”œβ”€β”€ πŸ“‚ sql/                              # SQL queries
β”‚   └── analytics_queries.sql            # Sample analytical queries
β”‚
β”œβ”€β”€ πŸ“„ requirements.txt                  # Python dependencies
β”œβ”€β”€ πŸ“„ .gitignore                        # Git exclusions
β”œβ”€β”€ πŸ“„ README.md                         # This file


πŸš€ Quick Start

Prerequisites

  • Docker and Docker Compose installed
  • Python 3.9+ installed
  • 8GB RAM minimum (recommended: 16GB)
  • 10GB disk space for Docker volumes

Installation

  1. Clone the repository

    git clone https://github.com/yourusername/procurement-pipeline.git
    cd procurement-pipeline
  2. Install Python dependencies

    pip install -r requirements.txt
  3. Configure environment variables

    # Copy the example file
    cp .env.example .env
    
    # For Windows PowerShell:
    Copy-Item .env.example .env

    Note: Default values work for local development. For production, update passwords in .env

  4. Start all services

    cd docker
    docker-compose up -d
  5. Wait for services to be ready (~2 minutes)

    docker-compose ps
    # All services should show "healthy" or "Up"
  6. Initialize HDFS directories

    cd ..
    # Linux/Mac:
    bash scripts/setup_hdfs.sh
    
    # Windows PowerShell (if script execution disabled):
    docker exec hadoop_client hdfs dfs -mkdir -p /procurement/raw/orders /procurement/raw/stock /procurement/processed/aggregated_orders /procurement/processed/net_demand /procurement/output/supplier_orders /procurement/logs/exceptions

βœ… Your environment is ready!


πŸ“– Usage Guide

1. Generate Test Data

Generate operational data for a specific date:

# Generate for today
python scripts/data_generation/generate_all_data.py

# Generate for specific date
python scripts/data_generation/generate_all_data.py --date 2026-01-14

Output:

  • data/raw/orders/2026-01-14/ - 5 POS store order files (JSONL)
  • data/raw/stock/2026-01-14/ - 3 warehouse stock snapshots (JSONL)

2. Upload Data to HDFS

# Upload today's data
python scripts/upload_to_hdfs.py

# Upload specific date
python scripts/upload_to_hdfs.py --date 2026-01-14

HDFS Structure Created:

/procurement/
β”œβ”€β”€ raw/
β”‚   β”œβ”€β”€ orders/2026-01-14/
β”‚   β”‚   β”œβ”€β”€ orders_store_001.json
β”‚   β”‚   β”œβ”€β”€ orders_store_002.json
β”‚   β”‚   └── ...
β”‚   └── stock/2026-01-14/
β”‚       β”œβ”€β”€ stock_WH001.json
β”‚       └── ...
β”œβ”€β”€ processed/
β”‚   β”œβ”€β”€ aggregated_orders/
β”‚   └── net_demand/
β”œβ”€β”€ output/
β”‚   └── supplier_orders/
└── logs/
    └── exceptions/

3. Run the Pipeline

Option A: Apache Airflow (Recommended for production)

  1. Access Airflow UI: http://localhost:8081
  2. Login: admin / admin
  3. Enable the procurement_pipeline DAG
  4. Trigger manually or wait for scheduled run (22:00 daily)

Option B: Python Script (Quick testing)

python airflow/dags/procurement_pipeline_dag.py

4. Analyze Results

# Use built-in analysis tool
python scripts/analyze_data.py

Output displays:

  • βœ… PostgreSQL master data summary
  • βœ… HDFS data overview (orders & stock)
  • βœ… Combined analysis (top products with supplier info)

5. View Supplier Orders

# Local output
cat data/output/supplier_orders/supplier_orders_20260114.csv

# HDFS output
docker exec hadoop_client hdfs dfs -cat /procurement/output/supplier_orders/supplier_orders_20260114.csv

CSV Format:

supplier_code,supplier_name,sku,product_name,net_demand,case_size,order_quantity
SUP001,Tech Supplies Inc,SKU00001,Product A,45,12,48
SUP002,Office Goods Ltd,SKU00015,Product B,23,6,24

οΏ½ Screenshots

Airflow DAG Graph View

Airflow DAG Graph

The complete procurement pipeline with 7 tasks: initialize_presto_schema β†’ check_data_availability β†’ create_hive_tables β†’ validate_data_quality β†’ calculate_net_demand β†’ generate_supplier_orders β†’ cleanup_temp_tables


οΏ½πŸ”„ Data Flow

Pipeline Execution Flow

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 1: INITIALIZE PRESTO SCHEMA                                 β”‚
β”‚ β€’ CREATE SCHEMA IF NOT EXISTS hive.default                      β”‚
β”‚ β€’ Verify schema creation (idempotent setup)                      β”‚
β”‚ β€’ Ensures Presto can create tables on first run                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 2: CHECK DATA AVAILABILITY                                  β”‚
β”‚ β€’ Verify HDFS files exist for execution date                     β”‚
β”‚ β€’ Count POS order files (expect 5)                               β”‚
β”‚ β€’ Count warehouse stock files (expect 3)                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 3: CREATE HIVE TABLES                                       β”‚
β”‚ β€’ CREATE EXTERNAL TABLE orders (location: HDFS /raw/orders/)    β”‚
β”‚ β€’ CREATE EXTERNAL TABLE stock (location: HDFS /raw/stock/)      β”‚
β”‚ β€’ Format: JSON                                                   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 4: VALIDATE DATA QUALITY                                    β”‚
β”‚ β€’ Check: All products have primary supplier mapping             β”‚
β”‚ β€’ Check: No demand spikes >500% vs safety stock                 β”‚
β”‚ β€’ Check: No zero available stock with positive reserved         β”‚
β”‚ β€’ Check: No duplicate SKU records per warehouse                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 5: CALCULATE NET DEMAND                                     β”‚
β”‚ β€’ Aggregate orders by SKU across all stores                     β”‚
β”‚ β€’ Join with stock levels by SKU (sum across warehouses)         β”‚
β”‚ β€’ Formula: max(0, orders + safety_stock - free_stock)           β”‚
β”‚ β€’ Export: aggregated_orders & net_demand to HDFS /processed/    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 6: GENERATE SUPPLIER ORDERS                                 β”‚
β”‚ β€’ Join net_demand with replenishment_rules                      β”‚
β”‚ β€’ Apply case rounding: CEIL(net_demand / case_size) * case_sizeβ”‚
β”‚ β€’ Enforce MOQ: max(order_qty, min_order_quantity)               β”‚
β”‚ β€’ Filter: order_quantity > 0                                     β”‚
β”‚ β€’ Export: CSV to /data/output/ and HDFS /output/                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Step 7: CLEANUP TEMP TABLES                                      β”‚
β”‚ β€’ DROP TABLE IF EXISTS hive.default.orders                      β”‚
β”‚ β€’ DROP TABLE IF EXISTS hive.default.stock                       β”‚
β”‚ β€’ Log execution metrics                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Net Demand Calculation Formula

for each SKU:
    # Aggregate demand
    total_orders = SUM(quantity) FROM orders WHERE sku = ?
    
    # Aggregate stock
    total_available = SUM(available_stock) FROM stock WHERE sku = ?
    total_reserved = SUM(reserved_stock) FROM stock WHERE sku = ?
    free_stock = total_available - total_reserved
    
    # Get safety stock from replenishment rules
    safety_stock = SELECT safety_stock FROM rules WHERE sku = ?
    
    # Calculate net demand
    net_demand = MAX(0, total_orders + safety_stock - free_stock)
    
    # Apply case rounding
    case_size = SELECT case_size FROM rules WHERE sku = ?
    order_quantity = CEIL(net_demand / case_size) * case_size
    
    # Enforce MOQ
    min_order_qty = SELECT min_order_quantity FROM rules WHERE sku = ?
    final_order = MAX(order_quantity, min_order_qty) IF net_demand > 0

πŸ“Š Pipeline Details

Airflow DAG Configuration

Schedule: 0 22 * * * (Daily at 22:00 UTC)
Catchup: False (no backfilling)
Retries: 2 per task
Retry Delay: 5 minutes

Task Dependencies:

check_data_availability
         ↓
create_hive_tables
         ↓
validate_data_quality
         ↓
calculate_net_demand
         ↓
generate_supplier_orders
         ↓
cleanup_temp_tables

Data Quality Checks

Check Description Threshold
Supplier Mapping All ordered products must have primary supplier 0 unmapped
Demand Spike Orders shouldn't exceed 5x safety stock < 5% violations
Stock Consistency No reserved stock when available = 0 0 violations
Duplicate SKUs Each SKU appears once per warehouse snapshot 0 duplicates

πŸ–₯ Monitoring & Access

Web Interfaces

Service URL Credentials Purpose
Airflow UI http://localhost:8081 admin / admin DAG monitoring, logs, task execution
Presto UI http://localhost:8080 - Query monitoring, cluster status
HDFS NameNode http://localhost:9870 - HDFS browser, cluster health

Database Connections

# PostgreSQL (Master Data)
docker exec -it procurement_postgres psql -U procurement -d procurement_db
# OR: localhost:5433 / procurement / procurement123

# PostgreSQL (Airflow Metadata)
docker exec -it airflow_postgres psql -U airflow -d airflow_db
# OR: localhost:5434 / airflow / airflow

# Presto CLI
docker exec -it presto presto-cli

# HDFS CLI
docker exec -it hadoop_client hdfs dfs -ls /procurement/

Useful Commands

# View all containers
docker-compose ps

# View Airflow logs
docker-compose logs -f airflow_scheduler

# Check HDFS usage
docker exec hadoop_client hdfs dfs -du -h /procurement/

# Run Presto query
docker exec presto presto-cli --execute "SELECT COUNT(*) FROM hive.default.orders"

# View DAG execution history
docker exec airflow_webserver airflow dags list-runs -d procurement_pipeline

# Clear DAG run history
docker exec airflow_webserver airflow dags delete procurement_pipeline

πŸ” Analysis Tools

analyze_data.py

Quick data overview and system testing:

python scripts/analyze_data.py

Output includes:

  1. Master Data Summary

    • Product, supplier, warehouse, rules counts
  2. HDFS Data Overview

    • Latest data date available
    • Order items count & unique products
    • Stock records & availability
  3. Combined Analysis

    • Top 10 products ordered (from HDFS)
    • Product details with suppliers (from PostgreSQL)

SQL Analytics

Sample queries in sql/analytics_queries.sql:

-- Top products by order volume
SELECT sku, SUM(quantity) as total_qty
FROM hive.default.orders
GROUP BY sku
ORDER BY total_qty DESC
LIMIT 10;

-- Products with low stock
SELECT s.sku, s.available_stock, r.safety_stock
FROM hive.default.stock s
JOIN postgresql.public.replenishment_rules r ON s.sku = r.sku
WHERE s.available_stock < r.safety_stock;

-- Supplier order summary
SELECT supplier_code, COUNT(*) as products, SUM(order_quantity) as total_qty
FROM supplier_orders
GROUP BY supplier_code;

πŸ”§ Troubleshooting

Common Issues

1. Services not starting

Symptom: Container exits immediately or shows unhealthy

Solution:

# Check logs
docker-compose logs namenode
docker-compose logs presto

# Restart specific service
docker-compose restart namenode

# Full reset
docker-compose down -v
docker-compose up -d

2. Database connection error

Symptom: psycopg2.OperationalError: could not connect

Solution:

# Verify PostgreSQL is running
docker ps | grep postgres

# Test connection
docker exec procurement_postgres psql -U procurement -d procurement_db -c "SELECT 1"

# Check if port 5433 is available
netstat -an | grep 5433

3. HDFS upload failed

Symptom: hdfs: command not found or No such file or directory

Solution:

# Check Hadoop containers
docker ps | grep hadoop

# Verify namenode is accessible
curl http://localhost:9870

# Check HDFS safemode
docker exec namenode hdfs dfsadmin -safemode get

# Leave safemode if stuck
docker exec namenode hdfs dfsadmin -safemode leave

4. Presto query timeout

Symptom: Query exceeded maximum time limit

Solution:

# Check Presto is running
docker exec presto presto-cli --execute "SELECT 1"

# Verify Hive connector
docker exec presto cat /opt/presto-server/etc/catalog/hive.properties

# Restart Presto
docker-compose restart presto

5. Airflow DAG not appearing

Symptom: DAG not visible in UI

Solution:

# Check DAG file syntax
python airflow/dags/procurement_pipeline_dag.py

# Refresh DAGs
docker exec airflow_scheduler airflow dags list

# Check scheduler logs
docker-compose logs -f airflow_scheduler

Performance Tuning

# Increase Docker memory limit (Docker Desktop)
# Settings β†’ Resources β†’ Memory: 8GB minimum

# Increase Presto memory
# Edit docker/presto/config.properties:
# query.max-memory=2GB
# query.max-memory-per-node=1GB

# HDFS replication factor (single-node setup)
docker exec namenode hdfs dfs -setrep -w 1 /procurement/

🀝 Contributing

Contributions and suggestions are welcome!

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/your-feature
  3. Commit: git commit -m 'feat: add your feature'
  4. Push: git push origin feature/your-feature
  5. Open a Pull Request

πŸ“ License

Academic project - Fondements Big Data
Academic Year: 2025-2026


πŸ“ž Contact

For questions or suggestions, open an issue on GitHub.


Key Learnings

  • Distributed Storage with Hadoop HDFS
  • Federated Queries with Presto (cross-system JOINs)
  • Workflow Orchestration with Apache Airflow
  • Data Quality Validation in production pipelines
  • Batch Processing patterns for Big Data
  • Containerization with Docker Compose
  • Data Lake Architecture (raw/processed/output zones)
  • OLTP + OLAP hybrid systems

Quick Reference

Most Used Commands

# Start everything
cd docker && docker-compose up -d

# Generate & upload data
python scripts/data_generation/generate_all_data.py --date 2026-01-14
python scripts/upload_to_hdfs.py --date 2026-01-14

# Analyze results
python scripts/analyze_data.py

# Check HDFS
docker exec hadoop_client hdfs dfs -ls -R /procurement/

# Run Presto query
docker exec presto presto-cli --execute 'SELECT COUNT(*) FROM hive.default.orders'

# View Airflow logs
docker-compose -f docker/docker-compose.yml logs -f airflow_scheduler

# Stop everything
cd docker && docker-compose down

Project Statistics

  • Docker Containers: 9
  • Python Files: ~15
  • SQL Queries: ~20
  • Data Generators: 6
  • HDFS Directories: 7
  • PostgreSQL Tables: 5
  • Airflow Tasks: 7
  • Lines of Code: ~2000+

Acknowledgments

  • ENSA Al-Hoceima for the Big Data curriculum
  • Apache Software Foundation for Hadoop, Presto, and Airflow
  • PostgreSQL Global Development Group
  • Docker Community

Last Updated: January 14, 2026

About

Big Data procurement pipeline using Hadoop, Presto, and Airflow

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages