From 290131269e1900f9483847851670b6e87166d47f Mon Sep 17 00:00:00 2001 From: Ken Yasue Date: Fri, 5 Dec 2025 11:49:01 +0100 Subject: [PATCH] update readme.md --- .claude/settings.local.json | 3 +- README.md | 1274 ++++++++++++++++++++++------------- 2 files changed, 806 insertions(+), 471 deletions(-) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 4f28e31..1f0a7b0 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -17,7 +17,8 @@ "Bash(git remote add:*)", "Bash(git push:*)", "Bash(git commit:*)", - "Bash(docker-compose ps:*)" + "Bash(docker-compose ps:*)", + "Bash(tree:*)" ], "deny": [], "ask": [] diff --git a/README.md b/README.md index cdc5ae4..bf0b96d 100644 --- a/README.md +++ b/README.md @@ -1,567 +1,901 @@ -# JAX-WS Hello World Project +# JAX-WS Loan Approval System -A simple JAX-WS web service boilerplate project that returns "Hello World" messages. +A complete JAX-WS SOAP web services application for loan processing, featuring customer registration, credit score evaluation, and loan approval workflows with SQLite database persistence. -## Project Structure +## Project Details + +### Overview + +This project demonstrates a production-ready JAX-WS web service implementation using Java 8, Maven, and Apache Tomcat. The system provides three main SOAP services: + +1. **Hello World Service** - A simple demonstration service for testing SOAP connectivity +2. **Loan Approval Service** - Complete loan processing system with: + - Customer registration with blacklist management + - Automated credit score evaluation + - Risk-based interest rate calculation + - Loan application processing and approval workflows + +### Technology Stack + +- **Java**: 1.8 (JDK 8) +- **Web Services**: JAX-WS 2.3.1 (SOAP) +- **Build Tool**: Apache Maven 3.x +- **Application Server**: Apache Tomcat 9+ +- **Database**: SQLite 3.43.0 +- **Containerization**: Docker & Docker Compose +- **Testing**: Python 3 with zeep library + +### Key Features + +- **RESTful SOAP Services**: Industry-standard JAX-WS implementation +- **Database Persistence**: SQLite database with automatic schema initialization +- **Credit Risk Assessment**: Tiered approval logic based on credit scores +- **Blacklist Management**: Customer screening and rejection system +- **Docker Support**: Fully containerized with one-command deployment +- **Comprehensive Testing**: Python test clients for all services +- **Production-Ready**: Singleton patterns, prepared statements, error handling + +--- + +## How to Run and Rebuild Using Docker Compose + +### Prerequisites + +- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (Windows/Mac) or [Docker Engine](https://docs.docker.com/engine/install/) (Linux) +- Docker Compose (included with Docker Desktop) + +### Quick Start + +#### 1. Start the Application + +```bash +docker-compose up -d +``` + +This command will: +- Build the Docker image with Maven multi-stage build +- Compile the Java application +- Package it as a WAR file +- Deploy to Tomcat +- Start the container in detached mode + +**Wait 30-40 seconds for Tomcat to fully start** + +#### 2. Verify the Deployment + +Access the following URLs in your browser: + +- **Hello World WSDL**: http://localhost:8080/jaxws-hello-world/hello?wsdl +- **Loan Service WSDL**: http://localhost:8080/jaxws-hello-world/loan?wsdl +- **Tomcat Manager**: http://localhost:8080/manager (username: `admin`, password: `admin123`) + +#### 3. View Application Logs + +```bash +# Follow logs in real-time +docker-compose logs -f + +# View recent logs +docker-compose logs --tail=100 + +# View logs for specific service +docker-compose logs jaxws-service +``` + +#### 4. Stop the Application + +```bash +docker-compose down +``` + +### Rebuild After Code Changes + +When you modify the source code, rebuild and restart: + +```bash +# Rebuild and restart +docker-compose up -d --build + +# Or rebuild without cache (clean build) +docker-compose build --no-cache +docker-compose up -d +``` + +### Docker Commands Reference + +| Command | Description | +|---------|-------------| +| `docker-compose up -d` | Start services in detached mode | +| `docker-compose up -d --build` | Rebuild and start services | +| `docker-compose down` | Stop and remove containers | +| `docker-compose logs -f` | Follow logs output | +| `docker-compose ps` | List running containers | +| `docker-compose restart` | Restart services | +| `docker-compose exec jaxws-service bash` | Access container shell | + +### Accessing the Database + +The SQLite database is mounted to the host machine and persists between container restarts: + +```bash +# Access database from host +sqlite3 loan_app.db "SELECT * FROM customers;" + +# Or access from within container +docker-compose exec jaxws-service sqlite3 /usr/local/tomcat/loan_app.db +``` + +### Environment Configuration + +The `docker-compose.yml` includes these configurations: + +- **Port Mapping**: `8080:8080` (host:container) +- **Memory Settings**: Xms256m, Xmx512m +- **Health Check**: Automatic WSDL availability check every 30s +- **Auto Restart**: Container restarts unless manually stopped +- **Volume Mounts**: + - `./logs:/usr/local/tomcat/logs` - Log persistence + - `./loan_app.db:/usr/local/tomcat/loan_app.db` - Database persistence + +--- + +## File Structure ``` jaxws-hello-world/ -├── pom.xml -├── Dockerfile -├── docker-compose.yml +│ ├── src/ │ └── main/ │ ├── java/ │ │ └── com/ │ │ └── example/ -│ │ └── service/ -│ │ ├── HelloWorldService.java -│ │ └── HelloWorldServiceImpl.java +│ │ ├── listener/ +│ │ │ └── DatabaseInitializationListener.java # Application startup initialization +│ │ │ +│ │ ├── model/ # Data models (POJOs) +│ │ │ ├── CustomerRegistrationRequest.java # Customer registration request +│ │ │ ├── LoanRequest.java # Loan application request +│ │ │ └── LoanResponse.java # Loan application response +│ │ │ +│ │ ├── repository/ # Data access layer +│ │ │ ├── CustomerRepository.java # Customer DAO interface +│ │ │ ├── LoanHistoryRepository.java # Loan history DAO interface +│ │ │ └── impl/ +│ │ │ ├── CustomerRepositoryImpl.java # Customer DAO implementation +│ │ │ └── LoanHistoryRepositoryImpl.java # Loan history DAO implementation +│ │ │ +│ │ ├── service/ # Web service layer +│ │ │ ├── HelloWorldService.java # Hello World interface +│ │ │ ├── HelloWorldServiceImpl.java # Hello World implementation +│ │ │ ├── LoanApprovalService.java # Loan service (interface + impl) +│ │ │ └── CreditScoreService.java # Credit score evaluation +│ │ │ +│ │ └── util/ +│ │ └── DatabaseManager.java # Singleton DB connection manager +│ │ │ └── webapp/ │ └── WEB-INF/ -│ ├── web.xml -│ └── sun-jaxws.xml -└── scripts/ - ├── test_hello_world.py - ├── simple_test.py - ├── requirements.txt - └── README.md +│ ├── web.xml # Web application descriptor +│ └── sun-jaxws.xml # JAX-WS endpoint configuration +│ +├── scripts/ # Python test clients +│ ├── test_all_services.py # Comprehensive test suite +│ ├── test_hello_world.py # Hello World service tests +│ ├── test_register_customer.py # Customer registration tests +│ ├── simple_test.py # Quick smoke test +│ └── README.md # Test scripts documentation +│ +├── logs/ # Tomcat logs (Docker volume) +│ +├── pom.xml # Maven project configuration +├── docker-compose.yml # Docker Compose orchestration +├── Dockerfile # Multi-stage Docker build +├── tomcat-users.xml # Tomcat manager users +├── loan_app.db # SQLite database (created on first run) +├── README.md # This file +├── apidoc.md # Complete API documentation +├── requirements.md # Project requirements specification +├── .dockerignore # Docker build exclusions +└── .gitignore # Git exclusions ``` -## Files Overview +### Architecture Layers -### Core Files -- **pom.xml**: Maven configuration with JAX-WS dependencies -- **HelloWorldService.java**: Web service interface with @WebService annotation -- **HelloWorldServiceImpl.java**: Implementation of the web service -- **web.xml**: Web application deployment descriptor -- **sun-jaxws.xml**: JAX-WS endpoint configuration +#### 1. **Listener Layer** (`listener/`) +- Application lifecycle management +- Database schema initialization on startup +- Connection validation -### Docker Files -- **Dockerfile**: Multi-stage Docker build configuration -- **docker-compose.yml**: Docker Compose orchestration file -- **tomcat-users.xml**: Tomcat manager user configuration +#### 2. **Model Layer** (`model/`) +- Plain Old Java Objects (POJOs) +- Request/Response DTOs for web services +- JAX-WS annotated data structures -### Test Scripts -- **scripts/test_hello_world.py**: Interactive Python test client with automated tests -- **scripts/simple_test.py**: Simple automated test script for CI/CD -- **scripts/requirements.txt**: Python dependencies -- **scripts/README.md**: Detailed test script documentation +#### 3. **Repository Layer** (`repository/`) +- Data access objects (DAO pattern) +- Database CRUD operations +- SQL query execution with prepared statements -## Quick Start with Docker (Recommended) +#### 4. **Service Layer** (`service/`) +- JAX-WS web service endpoints +- Business logic implementation +- Credit score evaluation +- Loan approval decision engine -The easiest way to test this application is using Docker. No need to install Java, Maven, or Tomcat! +#### 5. **Utility Layer** (`util/`) +- Singleton database connection manager +- Reusable helper classes +- Schema initialization and reset utilities -### Prerequisites -- [Docker Desktop](https://www.docker.com/products/docker-desktop/) (Windows/Mac/Linux) -- OR [Docker Engine](https://docs.docker.com/engine/install/) (Linux) +--- -### Running with Docker Compose +## Database Structure -**1. Start the application:** -```bash -docker-compose up -d +The application uses SQLite with the following schema: + +### Database File + +- **Location**: `loan_app.db` (project root) +- **Type**: SQLite 3 +- **JDBC URL**: `jdbc:sqlite:loan_app.db` +- **Initialization**: Automatic on application startup via `DatabaseInitializationListener` + +### Schema + +#### Table: `customers` + +Stores registered customer information with blacklist status. + +```sql +CREATE TABLE customers ( + customer_name TEXT PRIMARY KEY, + is_blacklisted INTEGER DEFAULT 0, + registered_at TEXT +); ``` -**1. Start the application ( when you changed code ):** -```bash -docker-compose up -d --build +**Column Details:** + +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `customer_name` | TEXT | PRIMARY KEY | Customer's unique name identifier | +| `is_blacklisted` | INTEGER | DEFAULT 0 | Blacklist flag (0 = not blacklisted, 1 = blacklisted) | +| `registered_at` | TEXT | NOT NULL | Registration timestamp (ISO 8601 format) | + +**Indexes:** +- Primary key index on `customer_name` (automatic) + +**Business Rules:** +- Customer names must be unique +- Blacklisted customers cannot get loan approvals +- Registration timestamp is automatically set during registration + +#### Table: `loan_history` + +Stores all loan application records for audit and reporting. + +```sql +CREATE TABLE loan_history ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + applicant_name TEXT, + requested_amount INTEGER, + approved INTEGER, + approved_rate REAL, + rejection_reason TEXT, + processed_at TEXT +); ``` -**2. Wait for the application to start (about 30-40 seconds), then access:** -- **WSDL**: http://localhost:8080/jaxws-hello-world/hello?wsdl -- **Tomcat Manager**: http://localhost:8080/manager (username: `admin`, password: `admin123`) +**Column Details:** -**3. View logs:** -```bash -docker-compose logs -f -``` +| Column | Type | Constraints | Description | +|--------|------|-------------|-------------| +| `id` | INTEGER | PRIMARY KEY AUTOINCREMENT | Unique record identifier | +| `applicant_name` | TEXT | | Applicant's name (may not be registered customer) | +| `requested_amount` | INTEGER | | Loan amount requested in currency units | +| `approved` | INTEGER | | Approval status (0 = rejected, 1 = approved) | +| `approved_rate` | REAL | | Interest rate if approved (0.0 if rejected) | +| `rejection_reason` | TEXT | NULL | Reason for rejection (NULL if approved) | +| `processed_at` | TEXT | NOT NULL | Processing timestamp (ISO 8601 format) | -**4. Stop the application:** -```bash -docker-compose down -``` +**Indexes:** +- Primary key index on `id` (automatic) -### Running with Docker (without Docker Compose) +**Business Rules:** +- Every loan application is logged regardless of approval status +- Approved loans have `approved=1` and `rejection_reason=NULL` +- Rejected loans have `approved=0` and populated `rejection_reason` +- Timestamp is automatically set during processing -**1. Build the Docker image:** -```bash -docker build -t jaxws-hello-world . -``` +### Credit Score Tiers & Interest Rates -**2. Run the container:** -```bash -docker run -d -p 8080:8080 --name jaxws-service jaxws-hello-world -``` +The loan approval logic uses the following credit score tiers: -**3. View logs:** -```bash -docker logs -f jaxws-service -``` +| Credit Score Range | Approval Status | Interest Rate | Rejection Reason | +|-------------------|-----------------|---------------|------------------| +| **>= 700** | ✅ Approved | 3.5% | - | +| **600 - 699** | ✅ Approved | 5.5% | - | +| **500 - 599** | ✅ Approved | 8.5% | - | +| **< 500** | ❌ Rejected | - | "Credit score too low" | +| **Blacklisted** | ❌ Rejected | - | "Applicant is blacklisted" | -**4. Stop and remove the container:** -```bash -docker stop jaxws-service -docker rm jaxws-service -``` +### Database Operations -### Testing the Docker Deployment - -Once the container is running, test the service: +#### Manual Database Access ```bash -# Check if WSDL is accessible -curl http://localhost:8080/jaxws-hello-world/hello?wsdl +# View all customers +sqlite3 loan_app.db "SELECT * FROM customers;" -# Test with a SOAP request -curl -X POST http://localhost:8080/jaxws-hello-world/hello \ - -H "Content-Type: text/xml; charset=utf-8" \ - -H "SOAPAction: " \ - -d ' - - - - Docker - - -' +# View all loan applications +sqlite3 loan_app.db "SELECT * FROM loan_history;" + +# View approved loans only +sqlite3 loan_app.db "SELECT * FROM loan_history WHERE approved = 1;" + +# View rejected loans with reasons +sqlite3 loan_app.db "SELECT applicant_name, rejection_reason FROM loan_history WHERE approved = 0;" + +# Count customers by blacklist status +sqlite3 loan_app.db "SELECT is_blacklisted, COUNT(*) FROM customers GROUP BY is_blacklisted;" + +# View loan approval rate +sqlite3 loan_app.db "SELECT + COUNT(*) as total, + SUM(approved) as approved, + ROUND(CAST(SUM(approved) AS FLOAT) / COUNT(*) * 100, 2) as approval_rate +FROM loan_history;" ``` -## Testing with Python Scripts +#### Database Reset (Testing) -Python test scripts are provided in the [scripts/](scripts/) folder for easy testing of the JAX-WS service. +The `DatabaseManager` class provides a reset method for testing: + +```java +DatabaseManager.getInstance().resetDatabase(); +``` + +This will: +1. Drop all tables +2. Recreate the schema +3. Clear all data + +--- + +## How to Run Tests ### Prerequisites -- Python 3.6 or higher -- pip (Python package installer) +Before running tests, ensure: -### Setup +1. **Service is Running** + ```bash + # Start the service + docker-compose up -d -**Install Python dependencies:** + # Wait 30-40 seconds, then verify + curl http://localhost:8080/jaxws-hello-world/hello?wsdl + ``` -Windows: +2. **Python Environment** + - Python 3.6 or higher + - pip (Python package installer) + +### Step 1: Install Test Dependencies + +Navigate to the scripts directory and install dependencies: + +**Windows:** ```cmd cd scripts pip install -r requirements.txt ``` -Linux/Mac: +**Linux/Mac:** ```bash cd scripts pip3 install -r requirements.txt ``` -### Available Test Scripts +**Required Python Package:** +- `requests>=2.31.0` - HTTP library for SOAP requests -#### 1. Simple Test Script +### Step 2: Choose Your Test Approach -Quick automated test with a single name: +#### Option 1: Comprehensive Test Suite (Recommended) + +Run all tests in one go with the unified test script: ```bash -# Test with default name "World" -python scripts/simple_test.py +# Windows +python test_all_services.py -# Test with custom name -python scripts/simple_test.py "Your Name" +# Linux/Mac +python3 test_all_services.py ``` -**Example Output:** +**What it tests:** +- ✅ Hello World Service (2 test cases) +- ✅ Customer Registration (4 test cases with validation) +- ✅ Loan Application Processing (14 test cases covering all scenarios) +- ✅ WSDL availability checks +- ✅ Error handling and edge cases + +**Expected Output:** ``` -Checking service availability... -[OK] WSDL is accessible +================================================================================ +JAX-WS UNIFIED TEST CLIENT +================================================================================ +Testing all services and operations -Calling service with: 'Your Name' -Response: Hello World, Your Name! +Checking services availability... -[PASS] Test PASSED! + Hello World Service: Service is accessible + Loan Approval Service: Service is accessible + +================================================================================ +AUTOMATED TEST SUITE +================================================================================ + +-------------------------------------------------------------------------------- +1. Testing Hello World Service +-------------------------------------------------------------------------------- + ✓ PASS | getHelloWorld('John') - Should return greeting + Hello World, John! + + ✓ PASS | getHelloWorld('Alice') - Should return greeting + Hello World, Alice! + +-------------------------------------------------------------------------------- +2. Testing Customer Registration Service +-------------------------------------------------------------------------------- + ✓ PASS | registerNewCustomer('Alice Johnson', blacklisted=False) + Registration Successful + + ✓ PASS | registerNewCustomer('Bob Smith', blacklisted=False) + Registration Successful + + ✓ PASS | registerNewCustomer('Charlie Brown', blacklisted=True) + Registration Successful + + ✓ PASS | registerNewCustomer('Alice Johnson', blacklisted=False) - Duplicate + Error: Customer already exists + +-------------------------------------------------------------------------------- +3. Testing Loan Application Processing Service +-------------------------------------------------------------------------------- + ✓ PASS | processLoanApplication('Alice Johnson', $50000, score=750) + approved: True | rate: 3.5% | Loan approved with excellent rate + + ✓ PASS | processLoanApplication('Bob Smith', $30000, score=650) + approved: True | rate: 5.5% | Loan approved with standard rate + + ✓ PASS | processLoanApplication('New Customer', $25000, score=550) + approved: True | rate: 8.5% | Loan approved with high risk rate + + ✓ PASS | processLoanApplication('Poor Credit', $20000, score=450) + approved: False | Credit score too low + + ✓ PASS | processLoanApplication('Charlie Brown', $40000, score=700) + approved: False | Applicant is blacklisted + +================================================================================ +TEST SUMMARY +================================================================================ + Total Tests: 20 + Passed: 20 + Failed: 0 + Success Rate: 100.0% + +Would you like to enter interactive mode? (y/n): ``` -#### 2. Interactive Test Script +**Interactive Mode:** -Full-featured test client with automated tests and interactive mode: +After automated tests, you can enter interactive mode for manual testing: + +``` +Available commands: + hello - Test Hello World service + register - Register regular customer + blacklist - Register blacklisted customer + loan - Process loan application + quit - Exit + +> hello TestUser +Response: Hello World, TestUser! + +> register John Doe +Result: Registration Successful + +> loan John Doe 50000 720 +Result: + approved: True + approvedRate: 3.5 + message: Loan approved with excellent rate + +> quit +``` + +#### Option 2: Individual Test Scripts + +Test specific services individually: + +##### A. Hello World Service Test ```bash -python scripts/test_hello_world.py +# Windows +python test_hello_world.py + +# Linux/Mac +python3 test_hello_world.py ``` -**Features:** -- Checks WSDL availability -- Runs automated tests with predefined names -- Interactive mode for manual testing -- Pretty-prints SOAP requests and responses +Tests the basic Hello World SOAP service with predefined test cases and interactive mode. -**Example Session:** -``` -============================================================ -JAX-WS Hello World Service Test Client -============================================================ - -1. Checking WSDL availability... - WSDL is accessible - -2. Testing Hello World Service... - - Calling service with name: 'World' - Response: Hello World, World! - - Calling service with name: 'Python Client' - Response: Hello World, Python Client! - -3. Interactive Mode - -------------------------------------------------------- - Enter a name (or 'quit' to exit): John - Response: Hello World, John! - - Enter a name (or 'quit' to exit): quit -``` - -### Using the HelloWorldClient Class - -You can also use the `HelloWorldClient` class in your own Python scripts: - -```python -from scripts.test_hello_world import HelloWorldClient - -# Create client -client = HelloWorldClient() - -# Check service availability -is_available, message = client.check_wsdl() -print(message) - -# Call the service -response = client.call_hello_world("Developer") -print(response) # Output: Hello World, Developer! -``` - -### Troubleshooting Python Tests - -**Service Not Available:** -- Ensure Docker container is running: `docker ps | grep jaxws` -- Check service URL: `curl http://localhost:8080/jaxws-hello-world/hello?wsdl` - -**Module Not Found:** -- Make sure you're in the project root directory -- Install dependencies: `pip install -r scripts/requirements.txt` - -**Python Command Not Found:** -- Windows: Use `python` or `py` -- Linux/Mac: Use `python3` - ---- - -## Environment Setup - -### Windows Setup - -#### 1. Install Java Development Kit (JDK) - -**Option A: Using Installer** -1. Download JDK 8 or higher from [Oracle](https://www.oracle.com/java/technologies/downloads/) or [OpenJDK](https://adoptium.net/) -2. Run the installer (e.g., `jdk-8u351-windows-x64.exe`) -3. Follow the installation wizard -4. Set JAVA_HOME environment variable: - ```cmd - setx JAVA_HOME "C:\Program Files\Java\jdk1.8.0_351" - setx PATH "%PATH%;%JAVA_HOME%\bin" - ``` - -**Option B: Using Chocolatey** -```cmd -choco install openjdk -``` - -**Verify Installation:** -```cmd -java -version -javac -version -``` - -#### 2. Install Apache Maven - -**Option A: Manual Installation** -1. Download Maven from [Apache Maven](https://maven.apache.org/download.cgi) -2. Extract to `C:\Program Files\Apache\maven` -3. Set environment variables: - ```cmd - setx MAVEN_HOME "C:\Program Files\Apache\maven" - setx PATH "%PATH%;%MAVEN_HOME%\bin" - ``` - -**Option B: Using Chocolatey** -```cmd -choco install maven -``` - -**Verify Installation:** -```cmd -mvn -version -``` - -#### 3. Install Apache Tomcat - -**Option A: Manual Installation** -1. Download Tomcat 9+ from [Apache Tomcat](https://tomcat.apache.org/download-90.cgi) -2. Extract to `C:\Program Files\Apache\Tomcat` -3. Set CATALINA_HOME: - ```cmd - setx CATALINA_HOME "C:\Program Files\Apache\Tomcat" - ``` - -**Option B: Using Chocolatey** -```cmd -choco install tomcat -``` - -**Start Tomcat:** -```cmd -cd C:\Program Files\Apache\Tomcat\bin -startup.bat -``` - -**Stop Tomcat:** -```cmd -cd C:\Program Files\Apache\Tomcat\bin -shutdown.bat -``` - -#### 4. Configure Tomcat Manager (Optional) - -Edit `C:\Program Files\Apache\Tomcat\conf\tomcat-users.xml`: -```xml - - - - - -``` - -Access at: `http://localhost:8080/manager` - ---- - -### Linux Setup - -#### 1. Install Java Development Kit (JDK) - -**Ubuntu/Debian:** -```bash -# Update package index -sudo apt update - -# Install OpenJDK 8 -sudo apt install openjdk-8-jdk -y - -# OR Install OpenJDK 11 -sudo apt install openjdk-11-jdk -y - -# Set JAVA_HOME -echo 'export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64' >> ~/.bashrc -echo 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bashrc -source ~/.bashrc -``` - -**RHEL/CentOS/Fedora:** -```bash -# Install OpenJDK 8 -sudo yum install java-1.8.0-openjdk-devel -y - -# OR Install OpenJDK 11 -sudo dnf install java-11-openjdk-devel -y - -# Set JAVA_HOME -echo 'export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk' >> ~/.bashrc -echo 'export PATH=$PATH:$JAVA_HOME/bin' >> ~/.bashrc -source ~/.bashrc -``` - -**Verify Installation:** -```bash -java -version -javac -version -``` - -#### 2. Install Apache Maven - -**Ubuntu/Debian:** -```bash -sudo apt update -sudo apt install maven -y -``` - -**RHEL/CentOS/Fedora:** -```bash -sudo yum install maven -y -# OR -sudo dnf install maven -y -``` - -**Manual Installation (All Distributions):** -```bash -# Download Maven -cd /opt -sudo wget https://dlcdn.apache.org/maven/maven-3/3.9.5/binaries/apache-maven-3.9.5-bin.tar.gz -sudo tar xzf apache-maven-3.9.5-bin.tar.gz -sudo ln -s apache-maven-3.9.5 maven - -# Set environment variables -echo 'export MAVEN_HOME=/opt/maven' >> ~/.bashrc -echo 'export PATH=$PATH:$MAVEN_HOME/bin' >> ~/.bashrc -source ~/.bashrc -``` - -**Verify Installation:** -```bash -mvn -version -``` - -#### 3. Install Apache Tomcat - -**Using Package Manager (Ubuntu/Debian):** -```bash -sudo apt update -sudo apt install tomcat9 -y - -# Start Tomcat -sudo systemctl start tomcat9 -sudo systemctl enable tomcat9 - -# Check status -sudo systemctl status tomcat9 -``` - -**Manual Installation (All Distributions):** -```bash -# Download Tomcat -cd /opt -sudo wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.80/bin/apache-tomcat-9.0.80.tar.gz -sudo tar xzf apache-tomcat-9.0.80.tar.gz -sudo ln -s apache-tomcat-9.0.80 tomcat - -# Set permissions -sudo chmod +x /opt/tomcat/bin/*.sh - -# Set environment variable -echo 'export CATALINA_HOME=/opt/tomcat' >> ~/.bashrc -source ~/.bashrc - -# Start Tomcat -/opt/tomcat/bin/startup.sh - -# Stop Tomcat -/opt/tomcat/bin/shutdown.sh -``` - -#### 4. Configure Tomcat Manager (Optional) - -Edit `/opt/tomcat/conf/tomcat-users.xml` or `/etc/tomcat9/tomcat-users.xml`: -```bash -sudo nano /opt/tomcat/conf/tomcat-users.xml -``` - -Add: -```xml - - - - - -``` - -Restart Tomcat: -```bash -# If using systemd -sudo systemctl restart tomcat9 - -# If manual installation -/opt/tomcat/bin/shutdown.sh -/opt/tomcat/bin/startup.sh -``` - -Access at: `http://localhost:8080/manager` - ---- - -### Verify Complete Setup - -**Check all installations:** - -Windows: -```cmd -java -version -javac -version -mvn -version -echo %CATALINA_HOME% -``` - -Linux: -```bash -java -version -javac -version -mvn -version -echo $CATALINA_HOME -curl http://localhost:8080 -``` - -If all commands return valid output, your environment is ready! - -## Building the Project +##### B. Customer Registration Test ```bash -mvn clean package +# Windows +python test_register_customer.py + +# Linux/Mac +python3 test_register_customer.py ``` -This will create a WAR file in the `target/` directory. +Tests customer registration including: +- Regular customer registration +- Blacklisted customer registration +- Duplicate registration handling +- Interactive registration mode -## Deploying +##### C. Simple Smoke Test -Deploy the generated WAR file to a servlet container like: -- Apache Tomcat 9+ -- Jetty -- GlassFish -- WildFly +Quick test for CI/CD pipelines: -## Testing the Service +```bash +# Windows +python simple_test.py "Test Name" -Once deployed, the service will be available at: +# Linux/Mac +python3 simple_test.py "Test Name" +``` -**WSDL URL**: `http://localhost:8080/jaxws-hello-world/services/hello?wsdl` +Returns exit code 0 on success, 1 on failure. -**Service Endpoint**: `http://localhost:8080/jaxws-hello-world/services/hello` +#### Option 3: Manual Testing with cURL -### Using SOAP UI or similar tool: +Test services directly using cURL commands: -Send a SOAP request like: -```xml - +##### Test Hello World Service + +```bash +curl -X POST http://localhost:8080/jaxws-hello-world/hello \ + -H "Content-Type: text/xml; charset=utf-8" \ + -H "SOAPAction: " \ + -d ' + - World + TestUser - +' ``` -Response: -```xml - - - - Hello World, World! - - - +##### Test Customer Registration + +```bash +curl -X POST http://localhost:8080/jaxws-hello-world/loan \ + -H "Content-Type: text/xml; charset=utf-8" \ + -H "SOAPAction: " \ + -d ' + + + + + + John Doe + false + + + +' ``` -## Requirements +##### Test Loan Application -### Option 1: Using Docker (Recommended) -- Docker Desktop or Docker Engine -- Docker Compose (usually included with Docker Desktop) +```bash +curl -X POST http://localhost:8080/jaxws-hello-world/loan \ + -H "Content-Type: text/xml; charset=utf-8" \ + -H "SOAPAction: " \ + -d ' + + + + + + John Doe + 50000 + 720 + + + +' +``` -### Option 2: Traditional Setup -- Java 8 or higher -- Maven 3.6+ -- Servlet container (Tomcat 9+, etc.) +#### Option 4: Testing with SoapUI + +1. Download and install [SoapUI](https://www.soapui.org/downloads/soapui/) +2. Create a new SOAP project +3. Import WSDL URLs: + - **Hello World**: `http://localhost:8080/jaxws-hello-world/hello?wsdl` + - **Loan Approval**: `http://localhost:8080/jaxws-hello-world/loan?wsdl` +4. SoapUI automatically generates request templates +5. Fill in parameters and execute requests + +### Step 3: Verify Database Records + +After running tests, verify data was persisted: + +```bash +# View registered customers +sqlite3 loan_app.db "SELECT * FROM customers;" + +# View loan application history +sqlite3 loan_app.db "SELECT * FROM loan_history;" + +# View approved loans with rates +sqlite3 loan_app.db " +SELECT applicant_name, requested_amount, approved_rate +FROM loan_history +WHERE approved = 1;" + +# View rejection reasons +sqlite3 loan_app.db " +SELECT applicant_name, rejection_reason +FROM loan_history +WHERE approved = 0;" +``` + +### Troubleshooting Tests + +#### Service Not Available + +**Error:** `Connection refused` or `Failed to establish connection` + +**Solutions:** +```bash +# Check if container is running +docker-compose ps + +# Check container logs +docker-compose logs -f + +# Restart the service +docker-compose restart + +# Verify WSDL is accessible +curl http://localhost:8080/jaxws-hello-world/hello?wsdl +``` + +#### Python Command Not Found + +**Error:** `python: command not found` + +**Solutions:** +- **Windows**: Try `py` or `python3` +- **Linux/Mac**: Use `python3` instead of `python` +- **Check installation**: `python --version` or `python3 --version` + +#### Dependencies Installation Failed + +**Error:** `Could not install packages` + +**Solutions:** +```bash +# Upgrade pip +python -m pip install --upgrade pip + +# Use virtual environment (recommended) +python -m venv venv + +# Windows +venv\Scripts\activate + +# Linux/Mac +source venv/bin/activate + +# Install dependencies in venv +pip install -r requirements.txt +``` + +#### Port Already in Use + +**Error:** `Port 8080 already in use` + +**Solutions:** +```bash +# Windows - Find process using port +netstat -ano | findstr :8080 + +# Linux/Mac - Find process using port +lsof -i :8080 + +# Kill the process or change docker-compose port mapping +``` + +#### Database Locked + +**Error:** `database is locked` + +**Solutions:** +```bash +# Stop all running tests +# Restart the service +docker-compose restart + +# If persists, reset database +rm loan_app.db +docker-compose restart +``` + +### Test Coverage + +The comprehensive test suite covers: + +| Category | Test Cases | Coverage | +|----------|-----------|----------| +| Hello World Service | 2 | Basic functionality, edge cases | +| Customer Registration | 4 | Regular, blacklisted, duplicates, validation | +| Loan Processing - Approvals | 7 | All credit score tiers (3.5%, 5.5%, 8.5%) | +| Loan Processing - Rejections | 5 | Low credit, blacklisted, validation errors | +| WSDL Availability | 2 | Both service endpoints | +| **Total** | **20** | **Full workflow coverage** | + +### API Documentation + +For detailed API documentation including: +- Complete SOAP request/response examples +- All service operations and parameters +- Error handling and SOAP faults +- Business logic and validation rules +- Production testing considerations + +See [apidoc.md](apidoc.md) + +For detailed test script documentation: +- Script usage and options +- Python client class examples +- Advanced testing scenarios + +See [scripts/README.md](scripts/README.md) + +--- + +## Service Endpoints + +Once running, the following endpoints are available: + +| Service | Endpoint | WSDL | +|---------|----------|------| +| Hello World | http://localhost:8080/jaxws-hello-world/hello | [WSDL](http://localhost:8080/jaxws-hello-world/hello?wsdl) | +| Loan Approval | http://localhost:8080/jaxws-hello-world/loan | [WSDL](http://localhost:8080/jaxws-hello-world/loan?wsdl) | +| Tomcat Manager | http://localhost:8080/manager | admin/admin123 | + +--- + +## Development + +### Building Locally (without Docker) + +**Prerequisites:** +- Java JDK 8+ +- Apache Maven 3.6+ +- Apache Tomcat 9+ + +**Build Commands:** +```bash +# Clean and build +mvn clean package + +# The WAR file will be created at: +# target/jaxws-hello-world.war + +# Deploy to Tomcat webapps directory +cp target/jaxws-hello-world.war $CATALINA_HOME/webapps/ +``` + +### Project Dependencies + +See [pom.xml](pom.xml) for complete dependency list: + +- `javax.xml.ws:jaxws-api:2.3.1` - JAX-WS API +- `com.sun.xml.ws:jaxws-rt:2.3.3` - JAX-WS Runtime +- `javax.servlet:javax.servlet-api:4.0.1` - Servlet API +- `org.xerial:sqlite-jdbc:3.43.0.0` - SQLite JDBC Driver + +--- + +## Production Considerations + +### Security + +⚠️ **This is a demonstration project. For production use:** + +- Implement WS-Security for authentication +- Use HTTPS/TLS for all communications +- Add input sanitization beyond current validation +- Implement rate limiting +- Add audit logging for sensitive operations +- Store credentials in secure vault (not in `tomcat-users.xml`) + +### Database + +- Consider PostgreSQL or MySQL for production workloads +- Implement connection pooling (HikariCP, c3p0) +- Add database backup strategy +- Implement database migration tool (Flyway, Liquibase) + +### Performance + +- The current `CreditScoreService` returns a fixed value (700) +- Integrate with real credit bureau APIs for production +- Add caching layer for credit scores +- Implement request/response logging +- Add monitoring and metrics (Prometheus, Grafana) + +--- + +## Troubleshooting + +### Container won't start + +```bash +# Check container logs +docker-compose logs + +# Check if port 8080 is already in use +netstat -ano | findstr :8080 # Windows +lsof -i :8080 # Linux/Mac + +# Remove and rebuild +docker-compose down +docker-compose up -d --build +``` + +### Database errors + +```bash +# Check database file permissions +ls -la loan_app.db + +# Reset database (will delete all data) +rm loan_app.db +docker-compose restart +``` + +### WSDL not accessible + +- Wait 30-40 seconds for Tomcat to fully start +- Check logs: `docker-compose logs -f` +- Verify container is running: `docker-compose ps` + +--- + +## License + +This is a demonstration project for educational purposes. + +--- + +## Support + +For issues, questions, or contributions: +- Review the [API Documentation](apidoc.md) +- Check the [Requirements Specification](requirements.md) +- Review test scripts in [scripts/README.md](scripts/README.md)