Enterprise-grade auction system with real-time bidding, distributed messaging, and comprehensive session management
Features β’ Quick Start β’ Architecture β’ API β’ Contributing
- About
- Features
- Technology Stack
- Architecture
- Getting Started
- Usage Examples
- API Documentation
- Testing
- Deployment
- Contributing
- License
A comprehensive enterprise application for online auctions featuring real-time bidding, built with Jakarta EE 10 and modern Java technologies. Demonstrates production-grade patterns in distributed systems, message-driven architecture, and enterprise development.
- π Educational - Learn enterprise Java patterns and best practices
- π’ Production-Ready - Built with enterprise-grade technologies
- π Scalable - Distributed architecture with horizontal scaling support
- π Real-Time - WebSocket-based instant notifications
- π Secure - Comprehensive session and user management
| Feature | Description |
|---|---|
| π·οΈ Auction Management | Create, monitor, and manage auctions with automatic expiration |
| π° Real-Time Bidding | Thread-safe concurrent bid handling with instant validation |
| π₯ User Management | Registration, authentication, and activity tracking |
| π‘ Live Notifications | WebSocket-based real-time bid and auction updates |
| π Message Queue | JMS integration for asynchronous event processing |
| π Analytics | Comprehensive auction and bidding statistics |
| π§ͺ Testing Suite | Unit, integration, and performance tests |
- β‘ Thread-Safe Operations - ConcurrentHashMap and atomic operations
- π― Stateless EJBs - Horizontal scalability support
- π Event-Driven - Message-Driven Beans for decoupled processing
- π‘οΈ Filter Chain - Session validation and security filters
- π¦ Clean Architecture - DTOs for data encapsulation
| Category | Technologies |
|---|---|
| Backend | Java 11+, Jakarta EE 10, EJB 4.0.1, JMS 3.1.0, CDI 4.0.1 |
| Web Layer | Servlet API 6.0.0, WebSocket, JSP |
| Frontend | JavaScript ES6+, CSS3, WebSocket API |
| Build | Maven 3.x, Maven Compiler Plugin |
| Testing | JUnit 5.9.3, Mockito 5.3.1, Testcontainers 1.18.3, JaCoCo 0.8.8 |
| Server | GlassFish 7.x |
graph TB
Browser[π₯οΈ Web Browser]
WSClient[π WebSocket Client]
Servlet[π Servlets & Filters]
WSEndpoint[π‘ WebSocket Endpoints]
AuctionEJB[βοΈ Auction Service]
BidEJB[π° Bid Service]
UserEJB[π€ User Service]
SessionMgr[π Session Manager]
AuctionMgr[β° Auction Manager]
JMS[π¨ JMS Queue]
MDB[π¬ Message Driven Bean]
Browser -->|HTTP/HTTPS| Servlet
WSClient -->|WebSocket| WSEndpoint
Servlet --> AuctionEJB
Servlet --> BidEJB
Servlet --> UserEJB
Servlet --> SessionMgr
WSEndpoint --> AuctionMgr
WSEndpoint --> SessionMgr
BidEJB -->|Send| JMS
AuctionEJB -->|Send| JMS
JMS -->|Consume| MDB
MDB -->|Broadcast| WSEndpoint
AuctionMgr -.->|Monitor| AuctionEJB
classDef clientStyle fill:#4A90E2,stroke:#2E5C8A,stroke-width:3px,color:#fff
classDef webStyle fill:#F39C12,stroke:#C87F0A,stroke-width:3px,color:#fff
classDef businessStyle fill:#9B59B6,stroke:#7D3C98,stroke-width:3px,color:#fff
classDef messageStyle fill:#27AE60,stroke:#1E8449,stroke-width:3px,color:#fff
class Browser,WSClient clientStyle
class Servlet,WSEndpoint webStyle
class AuctionEJB,BidEJB,UserEJB,SessionMgr,AuctionMgr businessStyle
class JMS,MDB messageStyle
sequenceDiagram
participant U as π€ User
participant S as Servlet
participant B as Bid Service
participant J as JMS Queue
participant M as MDB
participant W as WebSocket
participant C as π± Clients
U->>+S: POST /auction/bid
S->>+B: placeBid()
alt β
Valid Bid
B->>B: Validate amount
B->>B: Update auction
B->>J: Send message
B-->>-S: BidDTO
S-->>-U: 200 OK
J->>+M: Deliver
M->>+W: Broadcast
W->>C: Push update
W-->>-M: Done
M-->>-J: Ack
else β Invalid Bid
B-->>S: Error
S-->>U: 400 Bad Request
end
graph TB
A[π’ New Bid]
B[π Auction Started]
C[π Auction Ended]
D[β Auction Cancelled]
E[βοΈ EJB Business Logic]
F[π¨ JMS Queue]
G[π¬ Message-Driven Bean]
H[π‘ WebSocket Manager]
I[π Session Manager]
J[π Browser 1]
K[π Browser 2]
L[π Browser N]
A --> E
B --> E
C --> E
D --> E
E --> F
F --> G
G --> H
H --> I
I --> J
I --> K
I --> L
classDef eventStyle fill:#E74C3C,stroke:#C0392B,stroke-width:3px,color:#fff
classDef processStyle fill:#3498DB,stroke:#2980B9,stroke-width:3px,color:#fff
classDef distStyle fill:#9B59B6,stroke:#8E44AD,stroke-width:3px,color:#fff
classDef clientStyle fill:#2ECC71,stroke:#27AE60,stroke-width:3px,color:#fff
class A,B,C,D eventStyle
class E,F,G processStyle
class H,I distStyle
class J,K,L clientStyle
graph TB
E1[π¦ Auction Entity]
E2[π¦ Bid Entity]
E3[π¦ User Entity]
D1[π AuctionDTO]
D2[π BidDTO]
D3[π BidUpdateMessage]
S1[βοΈ Auction Service]
S2[βοΈ Bid Service]
S3[βοΈ User Service]
SG1[π Auction Manager]
SG2[π Session Manager]
A1[π Notification MDB]
S1 --> E1
S2 --> E2
S3 --> E3
S1 --> D1
S2 --> D2
S2 --> D3
S1 -.->|Monitor| SG1
S2 -->|Publish| A1
S3 -.->|Track| SG2
A1 -->|Broadcast| SG2
classDef entityStyle fill:#4A90E2,stroke:#2E5C8A,stroke-width:3px,color:#fff
classDef dtoStyle fill:#F39C12,stroke:#C87F0A,stroke-width:3px,color:#fff
classDef serviceStyle fill:#9B59B6,stroke:#7D3C98,stroke-width:3px,color:#fff
classDef singletonStyle fill:#27AE60,stroke:#1E8449,stroke-width:3px,color:#fff
classDef asyncStyle fill:#E74C3C,stroke:#C0392B,stroke-width:3px,color:#fff
class E1,E2,E3 entityStyle
class D1,D2,D3 dtoStyle
class S1,S2,S3 serviceStyle
class SG1,SG2 singletonStyle
class A1 asyncStyle
| Pattern | Implementation | Purpose |
|---|---|---|
| Singleton | AuctionManagerSingleton, UserSessionManagerBean |
Shared state & lifecycle management |
| Stateless Session Bean | AuctionServiceBean, BidServiceBean |
Scalable, concurrent business logic |
| Message-Driven Bean | BidNotificationMDB |
Asynchronous event processing |
| DTO | AuctionDTO, BidDTO |
Data encapsulation & transfer |
| Front Controller | AuctionServlet |
Centralized request handling |
| Observer | WebSocket + JMS | Real-time event notification |
| Filter Chain | SessionFilter, AdminFilter |
Request preprocessing & security |
Ensure you have the following installed:
# Java 11+
java -version
# Maven 3.6+
mvn -version
# Git
git --versionGlassFish Server 7.x
- Download: glassfish.org/download
- Or use Docker:
docker pull glassfish:7.0.0-jdk11
# 1. Clone repository
git clone https://github.com/isharax9/AuctionSystem.git
cd AuctionSystem
# 2. Build project
mvn clean install
# 3. Run tests
mvn test
# 4. Package application
mvn package# Start GlassFish
cd $GLASSFISH_HOME/bin
./asadmin start-domain domain1
# Configure JMS Resources
./asadmin create-jms-resource --restype jakarta.jms.Queue \
--property Name=BidNotificationQueue jms/BidNotificationQueue
./asadmin create-jms-resource --restype jakarta.jms.QueueConnectionFactory \
jms/BidNotificationQueueFactorydocker run -d \
-p 8080:8080 \
-p 4848:4848 \
--name glassfish \
glassfish:7.0.0-jdk11# Using asadmin
./asadmin deploy target/AuctionSystem.war
# Verify deployment
./asadmin list-applications| Service | URL | Purpose |
|---|---|---|
| Main App | http://localhost:8080/AuctionSystem/ |
Primary interface |
| Real-Time | http://localhost:8080/AuctionSystem/real-time-notifications.html |
Live updates |
| Session Admin | http://localhost:8080/AuctionSystem/session-admin |
Admin panel |
| Admin Console | http://localhost:4848 |
GlassFish admin |
@Inject
private AuctionServiceRemote auctionService;
public void createAuction() {
AuctionDTO auction = auctionService.createAuction(
"Vintage Camera",
"Rare 1950s Leica M3 in excellent condition",
250.0, // Starting price
3, // Duration: 3 hours
30 // Duration: 30 minutes
);
System.out.println("Created: " + auction.getAuctionId());
}@Inject
private BidServiceRemote bidService;
public boolean placeBid(Long auctionId, String username, double amount) {
BidDTO bid = bidService.placeBid(auctionId, username, amount);
return bid != null; // Returns true if successful
}// Connect to WebSocket
const socket = new WebSocket('ws://localhost:8080/AuctionSystem/auction-updates');
// Handle incoming updates
socket.onmessage = (event) => {
const update = JSON.parse(event.data);
console.log(`New bid: $${update.bidAmount} by ${update.bidder}`);
// Update UI
document.getElementById('currentBid').textContent = `$${update.bidAmount}`;
document.getElementById('bidder').textContent = update.bidder;
};
// Send bid
function placeBid(auctionId, amount) {
socket.send(JSON.stringify({
type: 'BID',
auctionId: auctionId,
amount: amount
}));
}| Method | Endpoint | Description | Request Body |
|---|---|---|---|
GET |
/auction |
List active auctions | - |
GET |
/auction/{id} |
Get auction details | - |
POST |
/auction |
Create new auction | AuctionDTO |
POST |
/auction/{id}/bid |
Place a bid | BidDTO |
GET |
/auction/history |
Completed auctions | ?page=1&size=10 |
POST |
/auction/{id}/close |
Close auction early | - |
GET |
/session-admin |
Active sessions | - |
Request:
POST /auction
Content-Type: application/json
{
"title": "Antique Vase",
"description": "Ming Dynasty ceramic vase, authenticated",
"startingPrice": 1000.0,
"durationHours": 4,
"durationMinutes": 30
}Response:
{
"auctionId": 1,
"title": "Antique Vase",
"startingPrice": 1000.0,
"currentHighestBid": 1000.0,
"currentHighestBidder": null,
"startTime": "2024-01-15T10:00:00",
"endTime": "2024-01-15T14:30:00",
"active": true,
"totalBidsCount": 0,
"status": "ACTIVE"
}Request:
POST /auction/1/bid
Content-Type: application/json
{
"username": "bidder123",
"amount": 1100.0
}Response:
{
"bidId": 1,
"auctionId": 1,
"username": "bidder123",
"amount": 1100.0,
"timestamp": "2024-01-15T10:15:00",
"valid": true
}AuctionSystem/
βββ src/main/java/com/auction/
β βββ config/ # WebSocket configuration
β βββ dto/ # Data Transfer Objects
β βββ ejb/ # Enterprise JavaBeans
β β βββ *ServiceBean.java # Business logic
β β βββ *ServiceRemote.java # Remote interfaces
β β βββ AuctionManagerSingleton.java
β β βββ BidNotificationMDB.java
β βββ entity/ # Domain entities (Auction, Bid, User)
β βββ filter/ # Servlet filters (Session, Admin, Encoding)
β βββ servlet/ # Web servlets
β βββ session/ # Session management
β βββ websocket/ # WebSocket endpoints
βββ src/main/webapp/
β βββ WEB-INF/web.xml # Deployment descriptor
β βββ css/ # Stylesheets
β βββ js/ # JavaScript modules
β βββ error/ # Error pages (404, 500)
β βββ *.jsp, *.html # Web pages
βββ src/test/java/ # Test suite
β βββ ejb/ # Unit tests
β βββ entity/ # Entity tests
β βββ integration/ # Integration tests
β βββ performance/ # Performance tests
βββ pom.xml # Maven configuration
βββ README.md
# All tests
mvn test
# Specific test class
mvn test -Dtest=AuctionServiceBeanTest
# With coverage report
mvn clean test jacoco:report
# View coverage
open target/site/jacoco/index.html| Category | Coverage Target |
|---|---|
| Overall | > 80% |
| Business Logic | > 90% |
| Entities | > 85% |
| Servlets | > 75% |
- β Unit Tests - EJB business logic, entity validation
- β Integration Tests - End-to-end auction workflows
- β Concurrency Tests - Thread safety verification
- β Performance Tests - Load and stress testing
mvn clean package -PprodFROM glassfish:7.0.0-jdk11
COPY target/AuctionSystem.war \
/opt/glassfish7/glassfish/domains/domain1/autodeploy/
EXPOSE 8080 4848
CMD ["asadmin", "start-domain", "--verbose"]# Build and run
docker build -t auction-system .
docker run -d -p 8080:8080 -p 4848:4848 --name auction auction-systemThis repository includes a container-based Heroku deployment because the
application requires a Jakarta EE runtime. The image builds the WAR with Maven,
runs it on GlassFish 7, configures the JMS resources, and binds GlassFish to the
dynamic PORT supplied by Heroku.
For manual deployment:
heroku create --stack container <app-name>
heroku container:login
heroku container:push web --app <app-name>
heroku container:release web --app <app-name>The GitHub Actions workflow in .github/workflows/deploy-heroku.yml deploys
every push to main. Configure these repository secrets:
HEROKU_API_KEY- token returned byheroku auth:tokenHEROKU_APP_NAME- the target Heroku application name
The workflow releases the image and verifies /AuctionSystem/ returns a
successful response before completing.
| Environment | Server | Database | Messaging |
|---|---|---|---|
| Dev | localhost | In-Memory | Local Queue |
| Staging | staging.example.com | PostgreSQL | ActiveMQ |
| Prod | www.example.com | PostgreSQL HA | ActiveMQ Cluster |
- Database persistence (PostgreSQL/MySQL + JPA)
- OAuth2/JWT authentication
- Payment gateway integration
- Image upload for auctions
- Email & SMS notifications
- Redis caching layer
- Kubernetes deployment
- Core auction management
- Real-time bidding with WebSocket
- JMS message-driven architecture
- Session management
- Comprehensive test suite
- Production-ready build
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
# 1. Fork and clone
git clone https://github.com/yourusername/AuctionSystem.git
# 2. Create feature branch
git checkout -b feature/AmazingFeature
# 3. Make changes and test
mvn test
# 4. Commit and push
git commit -m 'Add AmazingFeature'
git push origin feature/AmazingFeature
# 5. Open Pull RequestThis project is licensed under the MIT License - see LICENSE for details.
| Platform | Link |
|---|---|
| π§ Email | isharax9@gmail.com |
| π¬ Telegram | @mac_knight141 |
| πΌ LinkedIn | isharax9 |
| π GitHub | @isharax9 |
β Star the repository β’ π Report bugs β’ π‘ Suggest features β’ π Contribute code
- Jakarta EE Community - Enterprise platform
- GlassFish Team - Application server
- Maven & JUnit - Build and testing tools
- Open Source Contributors - Community support
Made with β€οΈ by isharax9