add unified test scripts for all services

This commit is contained in:
2025-12-05 11:41:36 +01:00
parent 2fe315b7df
commit 1f949579b3
6 changed files with 1526 additions and 3 deletions

553
apidoc.md Normal file
View File

@ -0,0 +1,553 @@
# API Documentation
## Overview
This project provides JAX-WS SOAP web services for a loan approval system. The system includes customer registration, loan application processing with credit score evaluation, and a simple Hello World demonstration service.
**Version:** 1.0
**Base URL:** `http://localhost:8080/jaxws-hello-world`
**Protocol:** SOAP 1.1 / HTTP
**Data Format:** XML
## Table of Contents
- [Services Overview](#services-overview)
- [Hello World Service](#hello-world-service)
- [Loan Approval Service](#loan-approval-service)
- [Data Models](#data-models)
- [Database Schema](#database-schema)
- [Error Handling](#error-handling)
- [Testing](#testing)
---
## Services Overview
| Service Name | Endpoint | WSDL | Description |
|-------------|----------|------|-------------|
| HelloWorldService | `/hello` | [WSDL](http://localhost:8080/jaxws-hello-world/hello?wsdl) | Simple demonstration service |
| LoanApprovalService | `/loan` | [WSDL](http://localhost:8080/jaxws-hello-world/loan?wsdl) | Customer registration and loan processing |
---
## Hello World Service
### Service Information
- **Endpoint:** `http://localhost:8080/jaxws-hello-world/hello`
- **WSDL:** `http://localhost:8080/jaxws-hello-world/hello?wsdl`
- **Namespace:** `http://service.example.com/`
### Methods
#### getHelloWorld
Returns a personalized greeting message.
**Operation:** `getHelloWorld`
**Input Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| name | string | Yes | Name to include in greeting |
**Returns:** `string` - Greeting message in format "Hello World, {name}!"
**SOAP Request Example:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.example.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:getHelloWorld>
<arg0>John</arg0>
</ser:getHelloWorld>
</soapenv:Body>
</soapenv:Envelope>
```
**SOAP Response Example:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getHelloWorldResponse xmlns:ns2="http://service.example.com/">
<return>Hello World, John!</return>
</ns2:getHelloWorldResponse>
</S:Body>
</S:Envelope>
```
---
## Loan Approval Service
### Service Information
- **Endpoint:** `http://localhost:8080/jaxws-hello-world/loan`
- **WSDL:** `http://localhost:8080/jaxws-hello-world/loan?wsdl`
- **Namespace:** `http://service.example.com/`
- **Database:** SQLite (`loan_app.db`)
### Methods
#### 1. registerNewCustomer
Registers a new customer in the system with optional blacklist status.
**Operation:** `registerNewCustomer`
**Input Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| request | CustomerRegistrationRequest | Yes | Customer registration details |
| └─ customerName | string | Yes | Customer's full name |
| └─ blacklisted | boolean | No | Blacklist status (default: false) |
**Returns:** `string` - Registration status message
**Possible Return Values:**
- `"Registration Successful"` - Customer registered successfully
- `"Error: Customer already exists"` - Customer name already in database
**SOAP Request Example:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.example.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:registerNewCustomer>
<arg0>
<customerName>John Doe</customerName>
<blacklisted>false</blacklisted>
</arg0>
</ser:registerNewCustomer>
</soapenv:Body>
</soapenv:Envelope>
```
**SOAP Response Example (Success):**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:registerNewCustomerResponse xmlns:ns2="http://service.example.com/">
<return>Registration Successful</return>
</ns2:registerNewCustomerResponse>
</S:Body>
</S:Envelope>
```
**SOAP Response Example (Duplicate):**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:registerNewCustomerResponse xmlns:ns2="http://service.example.com/">
<return>Error: Customer already exists</return>
</ns2:registerNewCustomerResponse>
</S:Body>
</S:Envelope>
```
**Business Rules:**
- Customer names must be unique
- Customer name cannot be null or empty
- Blacklist status is optional (defaults to false)
- Registration time is automatically recorded
#### 2. processLoanApplication
Processes a loan application with credit score-based approval logic.
**Operation:** `processLoanApplication`
**Input Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| request | LoanRequest | Yes | Loan application details |
| └─ applicantName | string | Yes | Applicant's full name |
| └─ requestedAmount | int | Yes | Loan amount requested (must be > 0) |
| └─ creditScore | int | No | Credit score (system may use default) |
**Returns:** `LoanResponse` - Loan decision result
**SOAP Request Example:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.example.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:processLoanApplication>
<arg0>
<applicantName>John Doe</applicantName>
<requestedAmount>50000</requestedAmount>
<creditScore>720</creditScore>
</arg0>
</ser:processLoanApplication>
</soapenv:Body>
</soapenv:Envelope>
```
**SOAP Response Example (Approved):**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:processLoanApplicationResponse xmlns:ns2="http://service.example.com/">
<return>
<approved>true</approved>
<approvedRate>3.5</approvedRate>
<rejectionReason></rejectionReason>
<message>Loan approved with excellent rate</message>
</return>
</ns2:processLoanApplicationResponse>
</S:Body>
</S:Envelope>
```
**SOAP Response Example (Rejected - Blacklisted):**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:processLoanApplicationResponse xmlns:ns2="http://service.example.com/">
<return>
<approved>false</approved>
<approvedRate>0.0</approvedRate>
<rejectionReason>Applicant is blacklisted</rejectionReason>
<message>Loan application rejected</message>
</return>
</ns2:processLoanApplicationResponse>
</S:Body>
</S:Envelope>
```
**SOAP Response Example (Rejected - Low Credit):**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:processLoanApplicationResponse xmlns:ns2="http://service.example.com/">
<return>
<approved>false</approved>
<approvedRate>0.0</approvedRate>
<rejectionReason>Credit score too low</rejectionReason>
<message>Loan application rejected</message>
</return>
</ns2:processLoanApplicationResponse>
</S:Body>
</S:Envelope>
```
**Credit Score Approval Logic:**
| Credit Score Range | Approval Status | Interest Rate | Message |
|-------------------|-----------------|---------------|---------|
| >= 700 | Approved | 3.5% | Loan approved with excellent rate |
| 600 - 699 | Approved | 5.5% | Loan approved with standard rate |
| 500 - 599 | Approved | 8.5% | Loan approved with high risk rate |
| < 500 | Rejected | N/A | Credit score too low |
| Blacklisted | Rejected | N/A | Applicant is blacklisted |
**Business Rules:**
- Blacklisted applicants are automatically rejected
- Applicant name cannot be null or empty
- Requested amount must be greater than 0
- Credit score is retrieved from CreditScoreService (default: 700)
- All loan applications are logged to loan_history table
- System records: applicant name, amount, approval status, rate, rejection reason, and timestamp
---
## Data Models
### CustomerRegistrationRequest
Request model for customer registration.
**Fields:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| customerName | string | Yes | Customer's full name (must be unique) |
| blacklisted | boolean | No | Whether customer is blacklisted (default: false) |
**Java Example:**
```java
CustomerRegistrationRequest request = new CustomerRegistrationRequest();
request.setCustomerName("John Doe");
request.setBlacklisted(false);
```
### LoanRequest
Request model for loan application.
**Fields:**
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| applicantName | string | Yes | Applicant's full name |
| requestedAmount | int | Yes | Loan amount in currency units (must be > 0) |
| creditScore | int | No | Credit score (0-850 scale) |
**Java Example:**
```java
LoanRequest request = new LoanRequest();
request.setApplicantName("John Doe");
request.setRequestedAmount(50000);
request.setCreditScore(720);
```
### LoanResponse
Response model for loan application result.
**Fields:**
| Field | Type | Description |
|-------|------|-------------|
| approved | boolean | Whether the loan was approved |
| approvedRate | double | Interest rate if approved (0.0 if rejected) |
| rejectionReason | string | Reason for rejection (null if approved) |
| message | string | Human-readable status message |
**Java Example:**
```java
LoanResponse response = loanService.processLoanApplication(request);
if (response.isApproved()) {
System.out.println("Approved at " + response.getApprovedRate() + "%");
} else {
System.out.println("Rejected: " + response.getRejectionReason());
}
```
---
## Database Schema
The service uses SQLite database (`loan_app.db`) with the following schema:
### customers
Stores registered customer information.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| customer_name | TEXT | PRIMARY KEY | Customer's unique name |
| is_blacklisted | INTEGER | DEFAULT 0 | Blacklist status (0=false, 1=true) |
| registered_at | TEXT | | Registration timestamp (ISO 8601) |
**Indexes:**
- Primary key on `customer_name`
### loan_history
Stores all loan application records.
| Column | Type | Constraints | Description |
|--------|------|-------------|-------------|
| id | INTEGER | PRIMARY KEY AUTOINCREMENT | Unique record ID |
| applicant_name | TEXT | | Applicant's name |
| requested_amount | INTEGER | | Loan amount requested |
| approved | INTEGER | | Approval status (0=rejected, 1=approved) |
| approved_rate | REAL | | Interest rate if approved |
| rejection_reason | TEXT | | Reason for rejection (null if approved) |
| processed_at | TEXT | | Processing timestamp (ISO 8601) |
**Indexes:**
- Primary key on `id`
---
## Error Handling
### SOAP Faults
The service returns SOAP faults for validation errors and invalid requests.
**Common SOAP Fault Example:**
```xml
<?xml version="1.0" encoding="UTF-8"?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault>
<faultcode>S:Server</faultcode>
<faultstring>Customer name cannot be null or empty</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
```
### Validation Rules
#### registerNewCustomer
- **SOAP Fault:** Customer name is null or empty
- **Response:** "Error: Customer already exists" (not a fault, returned as normal response)
#### processLoanApplication
- **SOAP Fault:** Applicant name is null or empty
- **SOAP Fault:** Requested amount is 0 or negative
- **Normal Response:** Rejection due to blacklist or low credit score
### HTTP Status Codes
| Status Code | Description |
|-------------|-------------|
| 200 OK | Request processed successfully (including business logic rejections) |
| 500 Internal Server Error | SOAP fault or server error |
---
## Testing
### Using Python Test Scripts
The project includes Python test clients for easy testing:
#### Unified Test Script (Recommended)
Test all services with a single comprehensive script:
```bash
cd scripts
python test_all_services.py
```
This script includes:
- Automated test suite with 20+ test cases
- Tests all three service operations
- Interactive mode for manual testing
- Clear pass/fail indicators with summary
#### Individual Service Tests
Test specific services:
```bash
# Test Hello World Service
python test_hello_world.py
# Test Customer Registration
python test_register_customer.py
```
### Using cURL
#### 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 '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.example.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:getHelloWorld>
<arg0>Test</arg0>
</ser:getHelloWorld>
</soapenv:Body>
</soapenv:Envelope>'
```
#### Register Customer
```bash
curl -X POST http://localhost:8080/jaxws-hello-world/loan \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: " \
-d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.example.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:registerNewCustomer>
<arg0>
<customerName>John Doe</customerName>
<blacklisted>false</blacklisted>
</arg0>
</ser:registerNewCustomer>
</soapenv:Body>
</soapenv:Envelope>'
```
#### Process Loan Application
```bash
curl -X POST http://localhost:8080/jaxws-hello-world/loan \
-H "Content-Type: text/xml; charset=utf-8" \
-H "SOAPAction: " \
-d '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ser="http://service.example.com/">
<soapenv:Header/>
<soapenv:Body>
<ser:processLoanApplication>
<arg0>
<applicantName>John Doe</applicantName>
<requestedAmount>50000</requestedAmount>
<creditScore>720</creditScore>
</arg0>
</ser:processLoanApplication>
</soapenv:Body>
</soapenv:Envelope>'
```
### Using SoapUI
1. Create a new SOAP project
2. Import WSDL:
- HelloWorldService: `http://localhost:8080/jaxws-hello-world/hello?wsdl`
- LoanApprovalService: `http://localhost:8080/jaxws-hello-world/loan?wsdl`
3. SoapUI will automatically generate request templates
4. Fill in the parameters and execute requests
### Checking the Database
After testing, you can inspect the SQLite database:
```bash
# View all customers
sqlite3 loan_app.db "SELECT * FROM customers;"
# View loan history
sqlite3 loan_app.db "SELECT * FROM loan_history;"
# View blacklisted customers
sqlite3 loan_app.db "SELECT * FROM customers WHERE is_blacklisted = 1;"
```
---
## Production Considerations
### Security
- **Authentication:** No authentication is currently implemented (add WS-Security for production)
- **HTTPS:** Use HTTPS in production environments
- **Input Validation:** All inputs are validated for null/empty values
- **SQL Injection:** Using PreparedStatements to prevent SQL injection
### Database
- **Location:** `loan_app.db` in project root (Docker volume mounted)
- **Persistence:** Database persists between container restarts
- **Backup:** Regular backups recommended for production
### Performance
- **Connection Pooling:** Consider adding connection pooling for production
- **Caching:** Credit score service can be cached
- **Monitoring:** Add logging and monitoring for production use
### Configuration
- **Credit Score Service:** Currently returns fixed value (700), integrate with real credit bureau API for production
- **Interest Rates:** Rates are hardcoded, should be configurable
- **Database Path:** Configurable via environment variable for different environments
---
## Support
For issues and feature requests, please refer to the project README.md.
**Project Repository:** See README.md for deployment instructions
**Docker Support:** Fully containerized with Docker Compose
**Test Scripts:** Located in `scripts/` directory