From 0322191af861a25e096d93c41b34f322765ae5fd Mon Sep 17 00:00:00 2001 From: Ken Yasue Date: Fri, 5 Dec 2025 09:11:38 +0100 Subject: [PATCH] Initial commit: JAX-WS Hello World Service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Complete JAX-WS Hello World implementation - Docker and Docker Compose support for easy deployment - Python test scripts for service validation - Comprehensive README with setup instructions for Windows and Linux - Maven configuration with JAX-WS dependencies ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .claude/settings.local.json | 20 + .dockerignore | 44 ++ .gitignore | 101 +++++ Dockerfile | 35 ++ README.md | 424 ++++++++++++++++++ docker-compose.yml | 23 + pom.xml | 68 +++ requirements.md | 186 ++++++++ scripts/README.md | 155 +++++++ scripts/requirements.txt | 4 + scripts/simple_test.py | 49 ++ scripts/test_hello_world.py | 208 +++++++++ .../example/service/HelloWorldService.java | 12 + .../service/HelloWorldServiceImpl.java | 17 + src/main/webapp/WEB-INF/sun-jaxws.xml | 9 + src/main/webapp/WEB-INF/web.xml | 25 ++ tomcat-users.xml | 16 + 17 files changed, 1396 insertions(+) create mode 100644 .claude/settings.local.json create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 pom.xml create mode 100644 requirements.md create mode 100644 scripts/README.md create mode 100644 scripts/requirements.txt create mode 100644 scripts/simple_test.py create mode 100644 scripts/test_hello_world.py create mode 100644 src/main/java/com/example/service/HelloWorldService.java create mode 100644 src/main/java/com/example/service/HelloWorldServiceImpl.java create mode 100644 src/main/webapp/WEB-INF/sun-jaxws.xml create mode 100644 src/main/webapp/WEB-INF/web.xml create mode 100644 tomcat-users.xml diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..4bfc467 --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,20 @@ +{ + "permissions": { + "allow": [ + "Bash(dir /B:*)", + "Bash(docker-compose up:*)", + "Bash(docker-compose logs:*)", + "Bash(curl:*)", + "Bash(docker exec:*)", + "Bash(winpty docker exec:*)", + "Bash(docker-compose down:*)", + "Bash(docker logs:*)", + "Bash(pip install:*)", + "Bash(python:*)", + "Bash(git init:*)", + "Bash(git add:*)" + ], + "deny": [], + "ask": [] + } +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..28c8267 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,44 @@ +# Maven build artifacts +target/ +*.jar +*.war +*.ear + +# IDE files +.idea/ +.vscode/ +*.iml +*.ipr +*.iws +.project +.classpath +.settings/ + +# OS files +.DS_Store +Thumbs.db + +# Git files +.git/ +.gitignore + +# Docker files +Dockerfile +docker-compose.yml +.dockerignore + +# Logs +logs/ +*.log + +# Documentation +README.md + +# Test files +*.test + +# Temporary files +*.tmp +*.bak +*.swp +*~ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..646b893 --- /dev/null +++ b/.gitignore @@ -0,0 +1,101 @@ +# Maven +target/ +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties +.mvn/wrapper/maven-wrapper.jar + +# Java +*.class +*.jar +*.war +*.ear +*.logs +*.log +hs_err_pid* +replay_pid* + +# IDE - IntelliJ IDEA +.idea/ +*.iml +*.ipr +*.iws +out/ +.idea_modules/ + +# IDE - Eclipse +.project +.classpath +.settings/ +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.loadpath +.recommenders + +# IDE - VSCode +.vscode/ +*.code-workspace + +# IDE - NetBeans +nbproject/private/ +build/ +nbbuild/ +dist/ +nbdist/ +.nb-gradle/ + +# OS +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +Desktop.ini + +# Docker +logs/ +*.log + +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +venv/ +ENV/ +env/ +.venv +pip-log.txt +pip-delete-this-directory.txt +.pytest_cache/ +*.egg-info/ +dist/ +build/ + +# Temporary files +*.tmp +*.temp +*~ + +# Package Files +*.7z +*.dmg +*.gz +*.iso +*.rar +*.tar +*.zip diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..5c7b6f9 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +# Multi-stage Dockerfile for JAX-WS Hello World Service + +# Stage 1: Build the application +FROM maven:3.8.6-openjdk-8 AS builder + +# Set working directory +WORKDIR /app + +# Copy pom.xml and download dependencies (for better caching) +COPY pom.xml . +RUN mvn dependency:go-offline -B + +# Copy source code +COPY src ./src + +# Build the application +RUN mvn clean package -DskipTests + +# Stage 2: Run the application +FROM tomcat:9.0-jdk8 + +# Remove default Tomcat applications +RUN rm -rf /usr/local/tomcat/webapps/* + +# Copy the WAR file from builder stage +COPY --from=builder /app/target/jaxws-hello-world.war /usr/local/tomcat/webapps/jaxws-hello-world.war + +# Copy Tomcat configuration (optional - for manager access) +COPY tomcat-users.xml /usr/local/tomcat/conf/tomcat-users.xml + +# Expose Tomcat port +EXPOSE 8080 + +# Start Tomcat +CMD ["catalina.sh", "run"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..804d84d --- /dev/null +++ b/README.md @@ -0,0 +1,424 @@ +# JAX-WS Hello World Project + +A simple JAX-WS web service boilerplate project that returns "Hello World" messages. + +## Project Structure + +``` +jaxws-hello-world/ +โ”œโ”€โ”€ pom.xml +โ”œโ”€โ”€ src/ +โ”‚ โ””โ”€โ”€ main/ +โ”‚ โ”œโ”€โ”€ java/ +โ”‚ โ”‚ โ””โ”€โ”€ com/ +โ”‚ โ”‚ โ””โ”€โ”€ example/ +โ”‚ โ”‚ โ””โ”€โ”€ service/ +โ”‚ โ”‚ โ”œโ”€โ”€ HelloWorldService.java +โ”‚ โ”‚ โ””โ”€โ”€ HelloWorldServiceImpl.java +โ”‚ โ””โ”€โ”€ webapp/ +โ”‚ โ””โ”€โ”€ WEB-INF/ +โ”‚ โ”œโ”€โ”€ web.xml +โ”‚ โ””โ”€โ”€ sun-jaxws.xml +``` + +## Files Overview + +- **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 +- **Dockerfile**: Multi-stage Docker build configuration +- **docker-compose.yml**: Docker Compose orchestration file +- **tomcat-users.xml**: Tomcat manager user configuration + +## Quick Start with Docker (Recommended) + +The easiest way to test this application is using Docker. No need to install Java, Maven, or Tomcat! + +### 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 + +**1. Start the application:** +```bash +docker-compose up -d +``` + +**2. Wait for the application to start (about 30-40 seconds), then access:** +- **WSDL**: http://localhost:8080/jaxws-hello-world/services/hello?wsdl +- **Tomcat Manager**: http://localhost:8080/manager (username: `admin`, password: `admin123`) + +**3. View logs:** +```bash +docker-compose logs -f +``` + +**4. Stop the application:** +```bash +docker-compose down +``` + +### Running with Docker (without Docker Compose) + +**1. Build the Docker image:** +```bash +docker build -t jaxws-hello-world . +``` + +**2. Run the container:** +```bash +docker run -d -p 8080:8080 --name jaxws-service jaxws-hello-world +``` + +**3. View logs:** +```bash +docker logs -f jaxws-service +``` + +**4. Stop and remove the container:** +```bash +docker stop jaxws-service +docker rm jaxws-service +``` + +### Testing the Docker Deployment + +Once the container is running, test the service: + +```bash +# Check if WSDL is accessible +curl http://localhost:8080/jaxws-hello-world/services/hello?wsdl + +# Test with a SOAP request +curl -X POST http://localhost:8080/jaxws-hello-world/services/hello \ + -H "Content-Type: text/xml; charset=utf-8" \ + -H "SOAPAction: " \ + -d ' + + + + Docker + + +' +``` + +--- + +## 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 + +```bash +mvn clean package +``` + +This will create a WAR file in the `target/` directory. + +## Deploying + +Deploy the generated WAR file to a servlet container like: +- Apache Tomcat 9+ +- Jetty +- GlassFish +- WildFly + +## Testing the Service + +Once deployed, the service will be available at: + +**WSDL URL**: `http://localhost:8080/jaxws-hello-world/services/hello?wsdl` + +**Service Endpoint**: `http://localhost:8080/jaxws-hello-world/services/hello` + +### Using SOAP UI or similar tool: + +Send a SOAP request like: +```xml + + + + + World + + + +``` + +Response: +```xml + + + + Hello World, World! + + + +``` + +## Requirements + +### Option 1: Using Docker (Recommended) +- Docker Desktop or Docker Engine +- Docker Compose (usually included with Docker Desktop) + +### Option 2: Traditional Setup +- Java 8 or higher +- Maven 3.6+ +- Servlet container (Tomcat 9+, etc.) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..62630ed --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,23 @@ +version: '3.8' + +services: + jaxws-service: + build: + context: . + dockerfile: Dockerfile + container_name: jaxws-hello-world + ports: + - "8080:8080" + environment: + - CATALINA_OPTS=-Xms256m -Xmx512m + - TZ=UTC + volumes: + # Optional: Mount logs directory for debugging + - ./logs:/usr/local/tomcat/logs + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8080/jaxws-hello-world/services/hello?wsdl"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..4fcfe37 --- /dev/null +++ b/pom.xml @@ -0,0 +1,68 @@ + + + 4.0.0 + + com.example + jaxws-hello-world + 1.0-SNAPSHOT + war + + JAX-WS Hello World Service + JAX-WS Web Service Project Boilerplate + + + 1.8 + 1.8 + UTF-8 + + + + + + javax.xml.ws + jaxws-api + 2.3.1 + + + + + com.sun.xml.ws + jaxws-rt + 2.3.3 + + + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + + + + + jaxws-hello-world + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-war-plugin + 3.3.1 + + false + + + + + diff --git a/requirements.md b/requirements.md new file mode 100644 index 0000000..41ef7c6 --- /dev/null +++ b/requirements.md @@ -0,0 +1,186 @@ +ใ”่ฆๆœ›ใซใŠๅฟœใˆใ—ใพใ™ใ€‚ +ใƒ‡ใƒผใ‚ฟใƒ™ใƒผใ‚น๏ผˆSQLite๏ผ‰ใซๅฏพใ—ใฆใ€ใƒ†ใ‚นใƒˆใƒ‡ใƒผใ‚ฟใ‚„ใƒžใ‚นใ‚ฟใƒ‡ใƒผใ‚ฟใ‚’ไบ‹ๅ‰ใซๆŠ•ๅ…ฅใƒป็ฎก็†ใ™ใ‚‹ใŸใ‚ใฎ **ใ€Œ้กงๅฎข็™ป้ŒฒAPI (Data Input API)ใ€** ใ‚’ๆฉŸ่ƒฝ่ฆไปถใซ่ฟฝๅŠ ใ—ใพใ—ใŸใ€‚ + +ใ“ใ‚Œใซใ‚ˆใ‚Šใ€่‡ชๅ‹•ใƒ†ใ‚นใƒˆ็”Ÿๆˆใƒ„ใƒผใƒซใฏ **ใ€Œใƒ‡ใƒผใ‚ฟใฎๅ‚็…ง๏ผˆRead๏ผ‰ใ€** ใ ใ‘ใงใชใ **ใ€Œใƒ‡ใƒผใ‚ฟใฎๆฐธ็ถšๅŒ–๏ผˆWrite๏ผ‰ใ€** ใ‚„ใ€**ใ€Œ็™ป้Œฒๅ‡ฆ็†ใŒๆญฃใ—ใ่กŒใ‚ใ‚ŒใŸใ‹ใฎๆคœ่จผใ€** ใ‚’่กŒใ†ๅฟ…่ฆใŒๅ‡บใฆใใพใ™ใ€‚ + +ๆ›ดๆ–ฐใ•ใ‚ŒใŸ `requirements.md` ใงใ™ใ€‚ + +----- + +# Requirements: JAX-WS Loan Approval Service Demo (with SQLite & Data Input) + +## 1\. Project Overview + +This project serves as a target application to evaluate an **Automated Unit Test Generation Tool**. +It is a SOAP-based Web Service designed to simulate a loan approval process. It utilizes **SQLite** for data persistence and includes APIs for both **Loan Processing** (Business Logic) and **Customer Management** (Data Input). + +### 1.1 Objectives + + * **Dependency Injection Analysis:** Verify if the tool can detect dependencies and inject mocks. + * **Database Interaction:** Evaluate tests for both Reading (Select) and Writing (Insert) operations. + * **State Verification:** Verify if the tool can assert that data input via one API is correctly reflected in the database. + +----- + +## 2\. System Architecture + +### 2.1 Technology Stack + + * **Language:** Java 11 or higher + * **Protocol:** SOAP 1.2 + * **Framework:** JAX-WS (Jakarta XML Web Services) + * **Database:** **SQLite** + * **Library:** `org.xerial:sqlite-jdbc` + +### 2.2 Architectural Components + + * **Service Endpoint:** `LoanApprovalService` (Contains both Loan Logic and Customer Registration). + * **Data Access Layer (DAO):** Interfaces for DB I/O. + * **Infrastructure:** Concrete implementations using JDBC/SQLite. + +----- + +## 3\. Database Design (Schema) + +The application uses a local SQLite database (`loan_app.db`). + +### 3.1 Table: `customers` (Master Data) + +```sql +CREATE TABLE customers ( + customer_name TEXT PRIMARY KEY, + is_blacklisted INTEGER DEFAULT 0, -- 0: False, 1: True + registered_at TEXT +); +``` + +### 3.2 Table: `loan_history` (Transaction Data) + +```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 +); +``` + +----- + +## 4\. Data Models (POJOs) + +### 4.1 Input: `LoanRequest` (Process Logic) + +*(Existing Loan Request model)* + +### 4.2 Input: `CustomerRegistrationRequest` (Data Input) + +New POJO for registering customers. + +| Field Name | Type | Description | Constraints | +| :--- | :--- | :--- | :--- | +| `customerName` | `String` | Name to register | Unique, Not Empty | +| `blacklisted` | `boolean` | Initial blacklist status | - | + +### 4.3 Output: `LoanResponse` + +*(Existing Loan Response model)* + +----- + +## 5\. DB I/O API (Repository Layer) + +The `CustomerRepository` is updated to support Data Input. + +### 5.1 `CustomerRepository` (Read & Write) + +```java +public interface CustomerRepository { + /** + * Checks if the applicant is on the blacklist. + */ + boolean isBlacklisted(String name); + + /** + * Registers a new customer into the database. + * @param name Customer Name + * @param isBlacklisted Blacklist status + * @return true if registered, false if already exists. + */ + boolean registerCustomer(String name, boolean isBlacklisted); +} +``` + +### 5.2 `LoanHistoryRepository` (Write-Only) + +*(Same as previous version: saves loan results)* + +----- + +## 6\. Functional Requirements + +The `LoanApprovalService` now exposes two main Web Methods. + +### 6.1 Feature A: Customer Registration (Data Input API) + +**Method:** `registerNewCustomer(CustomerRegistrationRequest request)` + + * **Input Validation:** + * If `request.customerName` is null or empty, throw `SOAPFaultException`. + * **Business Logic:** + * Call `CustomerRepository.registerCustomer(name, blacklisted)`. + * **If returns true:** Return string `"Registration Successful"`. + * **If returns false (Duplicate):** Return string `"Error: Customer already exists"`. + * **Test Goal:** Verify that data passed to this method is correctly forwarded to the Repository's save method. + +### 6.2 Feature B: Loan Processing (Core Logic) + +**Method:** `processLoanApplication(LoanRequest request)` + +*(Logic remains the same as previous version)* + +1. **Validate** Inputs. +2. **Check Blacklist:** Call `CustomerRepository.isBlacklisted`. + * *Note for Integration Testing:* If `registerNewCustomer` was called previously with `blacklisted=true`, this check must return `true`. +3. **Check Credit Score** (External Mock). +4. **Decide Approval.** +5. **Save History:** Call `LoanHistoryRepository.saveHistory`. + +----- + +## 7\. Implementation Constraints + +### 7.1 Dependency Injection + +The Service must have setters for: + + * `setCustomerRepository(CustomerRepository repo)` + * `setLoanHistoryRepository(LoanHistoryRepository repo)` + * `setCreditScoreService(CreditScoreService service)` + +### 7.2 Database Initialization + +The `DatabaseManager` should include a method to `resetDatabase()` (DROP/CREATE tables) to ensure a clean state for integration tests. + +----- + +## 8\. Expected Test Scenarios (Target for Generator) + +The tool is expected to generate tests covering: + +1. **Data Input Unit Test (Mock):** + * Scenario: Call `registerNewCustomer("Alice", true)`. + * Assertion: Verify `customerRepository.registerCustomer("Alice", true)` was called exactly once. +2. **Data Input Logic Test:** + * Scenario: Repository returns `false` (Duplicate). + * Assertion: Service returns message `"Error: Customer already exists"`. +3. **Integration Flow (Optional but Ideal):** + * Step 1: Call `registerNewCustomer("BadUser", true)`. + * Step 2: Call `processLoanApplication` for "BadUser". + * Assertion: Loan is rejected immediately due to Blacklist. +4. **Process Flow with DB Recording:** + * Scenario: Loan Approved. + * Assertion: `loanHistoryRepository.saveHistory` is called with `approved=true`. \ No newline at end of file diff --git a/scripts/README.md b/scripts/README.md new file mode 100644 index 0000000..46a50b7 --- /dev/null +++ b/scripts/README.md @@ -0,0 +1,155 @@ +# Test Scripts for JAX-WS Hello World Service + +This folder contains test scripts to interact with the JAX-WS Hello World Service. + +## Python Test Script + +### Prerequisites + +- Python 3.6 or higher +- pip (Python package installer) + +### Installation + +1. **Install Python dependencies:** + + **Windows:** + ```cmd + cd scripts + pip install -r requirements.txt + ``` + + **Linux/Mac:** + ```bash + cd scripts + pip3 install -r requirements.txt + ``` + +### Running the Test Script + +Make sure the JAX-WS service is running (using Docker or traditional setup). + +**Windows:** +```cmd +python test_hello_world.py +``` + +**Linux/Mac:** +```bash +python3 test_hello_world.py +# OR +chmod +x test_hello_world.py +./test_hello_world.py +``` + +### What the Script Does + +The `test_hello_world.py` script: + +1. **Checks WSDL availability** - Verifies the service is running +2. **Tests with multiple names** - Calls the service with predefined test cases +3. **Interactive mode** - Allows you to enter custom names and see responses in real-time + +### Example Output + +``` +============================================================ +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! + + Calling service with name: 'JAX-WS User' + Response: Hello World, JAX-WS User! + + Calling service with name: 'Docker' + Response: Hello World, Docker! + +3. Interactive Mode + -------------------------------------------------------- + Enter a name (or 'quit' to exit): John + Response: Hello World, John! + + Enter a name (or 'quit' to exit): quit + +============================================================ +Test completed! +============================================================ +``` + +## Using the HelloWorldClient Class + +You can also use the `HelloWorldClient` class in your own Python scripts: + +```python +from test_hello_world import HelloWorldClient + +# Create client +client = HelloWorldClient() + +# Check if service is available +is_available, message = client.check_wsdl() +print(message) + +# Call the service +response = client.call_hello_world("Your Name") +print(response) # Output: Hello World, Your Name! +``` + +## Troubleshooting + +### Service Not Available + +If you get a connection error: + +1. Make sure the Docker container is running: + ```bash + docker ps | grep jaxws + ``` + +2. Check if the service is accessible: + ```bash + curl http://localhost:8080/jaxws-hello-world/hello?wsdl + ``` + +3. Restart the service: + ```bash + docker-compose restart + ``` + +### Python Not Found + +If you get "python: command not found": + +- **Windows**: Use `python` or `py` command +- **Linux/Mac**: Use `python3` command + +### Dependencies Not Installing + +If pip install fails: + +1. Make sure pip is up to date: + ```bash + python -m pip install --upgrade pip + ``` + +2. Try installing with sudo (Linux/Mac only): + ```bash + sudo pip3 install -r requirements.txt + ``` + +3. Use a virtual environment: + ```bash + python3 -m venv venv + source venv/bin/activate # On Windows: venv\Scripts\activate + pip install -r requirements.txt + ``` diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 0000000..f874ee9 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1,4 @@ +# Python dependencies for JAX-WS Hello World test scripts + +# HTTP library for making SOAP requests +requests>=2.31.0 diff --git a/scripts/simple_test.py b/scripts/simple_test.py new file mode 100644 index 0000000..06b8413 --- /dev/null +++ b/scripts/simple_test.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +""" +Simple non-interactive test script for JAX-WS Hello World Service +""" + +import sys +from test_hello_world import HelloWorldClient + + +def test_service(name=None): + """ + Simple test function + + Args: + name: Optional name to test with. If None, uses "World" + """ + if name is None: + name = "World" if len(sys.argv) < 2 else sys.argv[1] + + client = HelloWorldClient() + + # Check WSDL + print(f"Checking service availability...") + wsdl_ok, wsdl_msg = client.check_wsdl() + + if not wsdl_ok: + print(f"[FAIL] {wsdl_msg}") + sys.exit(1) + + print(f"[OK] {wsdl_msg}") + + # Call service + print(f"\nCalling service with: '{name}'") + result = client.call_hello_world(name) + print(f"Response: {result}") + + # Verify response format + expected_start = f"Hello World, {name}" + if result.startswith(expected_start): + print("\n[PASS] Test PASSED!") + return 0 + else: + print(f"\n[FAIL] Test FAILED! Expected response to start with: '{expected_start}'") + return 1 + + +if __name__ == "__main__": + exit_code = test_service() + sys.exit(exit_code) diff --git a/scripts/test_hello_world.py b/scripts/test_hello_world.py new file mode 100644 index 0000000..8046cbe --- /dev/null +++ b/scripts/test_hello_world.py @@ -0,0 +1,208 @@ +#!/usr/bin/env python3 +""" +Python script to test JAX-WS Hello World Service +""" + +import requests +import xml.etree.ElementTree as ET +from xml.dom import minidom + + +class HelloWorldClient: + """Client for Hello World SOAP Service""" + + def __init__(self, service_url="http://localhost:8080/jaxws-hello-world/hello"): + """ + Initialize the Hello World client + + Args: + service_url: The SOAP service endpoint URL + """ + self.service_url = service_url + self.wsdl_url = f"{service_url}?wsdl" + self.headers = { + 'Content-Type': 'text/xml; charset=utf-8', + 'SOAPAction': '' + } + + def create_soap_envelope(self, name): + """ + Create SOAP envelope for getHelloWorld request + + Args: + name: The name parameter for the hello world service + + Returns: + XML string of SOAP envelope + """ + soap_envelope = f""" + + + + + {name} + + +""" + return soap_envelope + + def call_hello_world(self, name): + """ + Call the Hello World SOAP service + + Args: + name: The name to send to the service + + Returns: + Response message from the service + """ + try: + # Create SOAP envelope + soap_request = self.create_soap_envelope(name) + + # Make the SOAP request + response = requests.post( + self.service_url, + data=soap_request, + headers=self.headers, + timeout=10 + ) + + # Check if request was successful + response.raise_for_status() + + # Parse the response + return self.parse_response(response.text) + + except requests.exceptions.RequestException as e: + return f"Error calling service: {str(e)}" + + def parse_response(self, response_xml): + """ + Parse the SOAP response + + Args: + response_xml: The XML response from the service + + Returns: + The return value from the service + """ + try: + # Parse XML + root = ET.fromstring(response_xml) + + # Find the return element + # Handle namespaces + namespaces = { + 'S': 'http://schemas.xmlsoap.org/soap/envelope/', + 'ns2': 'http://service.example.com/' + } + + # Find the return value + return_elem = root.find('.//ns2:getHelloWorldResponse/return', namespaces) + + if return_elem is not None: + return return_elem.text + else: + return "Could not find return value in response" + + except ET.ParseError as e: + return f"Error parsing response: {str(e)}" + + def check_wsdl(self): + """ + Check if WSDL is accessible + + Returns: + True if WSDL is accessible, False otherwise + """ + try: + response = requests.get(self.wsdl_url, timeout=5) + response.raise_for_status() + return True, "WSDL is accessible" + except requests.exceptions.RequestException as e: + return False, f"Cannot access WSDL: {str(e)}" + + def pretty_print_xml(self, xml_string): + """ + Pretty print XML string + + Args: + xml_string: XML string to format + + Returns: + Formatted XML string + """ + try: + parsed = minidom.parseString(xml_string) + return parsed.toprettyxml(indent=" ") + except Exception: + return xml_string + + +def main(): + """Main function to test the Hello World service""" + + print("=" * 60) + print("JAX-WS Hello World Service Test Client") + print("=" * 60) + print() + + # Create client + client = HelloWorldClient() + + # Check WSDL + print("1. Checking WSDL availability...") + wsdl_ok, wsdl_msg = client.check_wsdl() + print(f" {wsdl_msg}") + if not wsdl_ok: + print(" Service is not available. Make sure the service is running.") + return + print() + + # Test with different names + test_names = [ + "World", + "Python Client", + "JAX-WS User", + "Docker" + ] + + print("2. Testing Hello World Service...") + print() + + for name in test_names: + print(f" Calling service with name: '{name}'") + result = client.call_hello_world(name) + print(f" Response: {result}") + print() + + # Interactive mode + print("3. Interactive Mode") + print(" " + "-" * 56) + try: + while True: + user_input = input(" Enter a name (or 'quit' to exit): ").strip() + + if user_input.lower() in ['quit', 'exit', 'q']: + break + + if user_input: + result = client.call_hello_world(user_input) + print(f" Response: {result}") + print() + else: + print(" Please enter a valid name.") + + except KeyboardInterrupt: + print("\n Interrupted by user") + + print() + print("=" * 60) + print("Test completed!") + print("=" * 60) + + +if __name__ == "__main__": + main() diff --git a/src/main/java/com/example/service/HelloWorldService.java b/src/main/java/com/example/service/HelloWorldService.java new file mode 100644 index 0000000..53a9302 --- /dev/null +++ b/src/main/java/com/example/service/HelloWorldService.java @@ -0,0 +1,12 @@ +package com.example.service; + +import javax.jws.WebMethod; +import javax.jws.WebService; + +@WebService +public interface HelloWorldService { + + @WebMethod + String getHelloWorld(String name); + +} diff --git a/src/main/java/com/example/service/HelloWorldServiceImpl.java b/src/main/java/com/example/service/HelloWorldServiceImpl.java new file mode 100644 index 0000000..95e8f7c --- /dev/null +++ b/src/main/java/com/example/service/HelloWorldServiceImpl.java @@ -0,0 +1,17 @@ +package com.example.service; + +import javax.jws.WebService; + +@WebService( + endpointInterface = "com.example.service.HelloWorldService", + serviceName = "HelloWorldService", + portName = "HelloWorldPort" +) +public class HelloWorldServiceImpl implements HelloWorldService { + + @Override + public String getHelloWorld(String name) { + return "Hello World, " + name + "!"; + } + +} diff --git a/src/main/webapp/WEB-INF/sun-jaxws.xml b/src/main/webapp/WEB-INF/sun-jaxws.xml new file mode 100644 index 0000000..16f9355 --- /dev/null +++ b/src/main/webapp/WEB-INF/sun-jaxws.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..b083056 --- /dev/null +++ b/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,25 @@ + + + + JAX-WS Hello World Service + + + com.sun.xml.ws.transport.http.servlet.WSServletContextListener + + + + HelloWorldService + com.sun.xml.ws.transport.http.servlet.WSServlet + 1 + + + + HelloWorldService + /hello + + + diff --git a/tomcat-users.xml b/tomcat-users.xml new file mode 100644 index 0000000..205c25f --- /dev/null +++ b/tomcat-users.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + +