Initial commit: JAX-WS Hello World Service
- 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 <noreply@anthropic.com>
This commit is contained in:
20
.claude/settings.local.json
Normal file
20
.claude/settings.local.json
Normal file
@ -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": []
|
||||||
|
}
|
||||||
|
}
|
||||||
44
.dockerignore
Normal file
44
.dockerignore
Normal file
@ -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
|
||||||
|
*~
|
||||||
101
.gitignore
vendored
Normal file
101
.gitignore
vendored
Normal file
@ -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
|
||||||
35
Dockerfile
Normal file
35
Dockerfile
Normal file
@ -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"]
|
||||||
424
README.md
Normal file
424
README.md
Normal file
@ -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 '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.example.com/">
|
||||||
|
<soapenv:Header/>
|
||||||
|
<soapenv:Body>
|
||||||
|
<ser:getHelloWorld>
|
||||||
|
<arg0>Docker</arg0>
|
||||||
|
</ser:getHelloWorld>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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
|
||||||
|
<tomcat-users>
|
||||||
|
<role rolename="manager-gui"/>
|
||||||
|
<role rolename="manager-script"/>
|
||||||
|
<user username="admin" password="admin123" roles="manager-gui,manager-script"/>
|
||||||
|
</tomcat-users>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
<tomcat-users>
|
||||||
|
<role rolename="manager-gui"/>
|
||||||
|
<role rolename="manager-script"/>
|
||||||
|
<user username="admin" password="admin123" roles="manager-gui,manager-script"/>
|
||||||
|
</tomcat-users>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
||||||
|
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://service.example.com/">
|
||||||
|
<soapenv:Header/>
|
||||||
|
<soapenv:Body>
|
||||||
|
<ser:getHelloWorld>
|
||||||
|
<arg0>World</arg0>
|
||||||
|
</ser:getHelloWorld>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```xml
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soap:Body>
|
||||||
|
<ns2:getHelloWorldResponse xmlns:ns2="http://service.example.com/">
|
||||||
|
<return>Hello World, World!</return>
|
||||||
|
</ns2:getHelloWorldResponse>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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.)
|
||||||
23
docker-compose.yml
Normal file
23
docker-compose.yml
Normal file
@ -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
|
||||||
68
pom.xml
Normal file
68
pom.xml
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
|
||||||
|
http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.example</groupId>
|
||||||
|
<artifactId>jaxws-hello-world</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
|
||||||
|
<name>JAX-WS Hello World Service</name>
|
||||||
|
<description>JAX-WS Web Service Project Boilerplate</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- JAX-WS API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.xml.ws</groupId>
|
||||||
|
<artifactId>jaxws-api</artifactId>
|
||||||
|
<version>2.3.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- JAX-WS Runtime -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.sun.xml.ws</groupId>
|
||||||
|
<artifactId>jaxws-rt</artifactId>
|
||||||
|
<version>2.3.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Servlet API -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.servlet</groupId>
|
||||||
|
<artifactId>javax.servlet-api</artifactId>
|
||||||
|
<version>4.0.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>jaxws-hello-world</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
<configuration>
|
||||||
|
<source>1.8</source>
|
||||||
|
<target>1.8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-war-plugin</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
<configuration>
|
||||||
|
<failOnMissingWebXml>false</failOnMissingWebXml>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
186
requirements.md
Normal file
186
requirements.md
Normal file
@ -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`.
|
||||||
155
scripts/README.md
Normal file
155
scripts/README.md
Normal file
@ -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
|
||||||
|
```
|
||||||
4
scripts/requirements.txt
Normal file
4
scripts/requirements.txt
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Python dependencies for JAX-WS Hello World test scripts
|
||||||
|
|
||||||
|
# HTTP library for making SOAP requests
|
||||||
|
requests>=2.31.0
|
||||||
49
scripts/simple_test.py
Normal file
49
scripts/simple_test.py
Normal file
@ -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)
|
||||||
208
scripts/test_hello_world.py
Normal file
208
scripts/test_hello_world.py
Normal file
@ -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"""<?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>{name}</arg0>
|
||||||
|
</ser:getHelloWorld>
|
||||||
|
</soapenv:Body>
|
||||||
|
</soapenv:Envelope>"""
|
||||||
|
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()
|
||||||
12
src/main/java/com/example/service/HelloWorldService.java
Normal file
12
src/main/java/com/example/service/HelloWorldService.java
Normal file
@ -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);
|
||||||
|
|
||||||
|
}
|
||||||
17
src/main/java/com/example/service/HelloWorldServiceImpl.java
Normal file
17
src/main/java/com/example/service/HelloWorldServiceImpl.java
Normal file
@ -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 + "!";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
9
src/main/webapp/WEB-INF/sun-jaxws.xml
Normal file
9
src/main/webapp/WEB-INF/sun-jaxws.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<endpoints xmlns="http://java.sun.com/xml/ns/jax-ws/ri/runtime" version="2.0">
|
||||||
|
|
||||||
|
<endpoint
|
||||||
|
name="HelloWorldService"
|
||||||
|
implementation="com.example.service.HelloWorldServiceImpl"
|
||||||
|
url-pattern="/hello"/>
|
||||||
|
|
||||||
|
</endpoints>
|
||||||
25
src/main/webapp/WEB-INF/web.xml
Normal file
25
src/main/webapp/WEB-INF/web.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
|
||||||
|
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
|
||||||
|
version="4.0">
|
||||||
|
|
||||||
|
<display-name>JAX-WS Hello World Service</display-name>
|
||||||
|
|
||||||
|
<listener>
|
||||||
|
<listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
|
||||||
|
</listener>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>HelloWorldService</servlet-name>
|
||||||
|
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
|
||||||
|
<load-on-startup>1</load-on-startup>
|
||||||
|
</servlet>
|
||||||
|
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>HelloWorldService</servlet-name>
|
||||||
|
<url-pattern>/hello</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
|
</web-app>
|
||||||
16
tomcat-users.xml
Normal file
16
tomcat-users.xml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<tomcat-users xmlns="http://tomcat.apache.org/xml"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://tomcat.apache.org/xml tomcat-users.xsd"
|
||||||
|
version="1.0">
|
||||||
|
|
||||||
|
<!-- Define roles -->
|
||||||
|
<role rolename="manager-gui"/>
|
||||||
|
<role rolename="manager-script"/>
|
||||||
|
<role rolename="manager-jmx"/>
|
||||||
|
<role rolename="manager-status"/>
|
||||||
|
|
||||||
|
<!-- Define admin user -->
|
||||||
|
<user username="admin" password="admin123" roles="manager-gui,manager-script,manager-jmx,manager-status"/>
|
||||||
|
|
||||||
|
</tomcat-users>
|
||||||
Reference in New Issue
Block a user