Compare commits

...
5 Commits
Author SHA1 Message Date
james.maes 7d465d401a feat: Java 21 LTS migration with qbit-build-parent 1.5.0 (#2)
* feat: migrate to Java 21 with qbit-build-parent 1.5.0

* fix: update qbit-build-parent to 1.5.1 for JUnit 6 compatibility

* chore: retrigger CI after Maven Central sync
2025-12-28 16:36:02 -06:00
james.maes 69fc7d0883 docs: Standardize README 2025-12-24 14:20:15 -06:00
james.maes 60a689374b ci: Add GitHub release configuration 2025-12-24 12:44:00 -06:00
CircleCI 7aeceac1b1 Bump version to v0.2.1 [skip ci] 2025-09-16 19:46:33 +00:00
james.maes f59fdb68d1 fix: bump orb version for issue with tag released 2025-09-16 14:45:14 -05:00
4 changed files with 141 additions and 137 deletions

No files matched your search

+1 -1
View File
@@ -1,7 +1,7 @@
version: 2.1
orbs:
qqq-orb: kingsrook/qqq-orb@0.3.5
qqq-orb: kingsrook/qqq-orb@0.5.0
workflows:
+31
View File
@@ -0,0 +1,31 @@
# GitHub Release Configuration
# Auto-generates release notes from PR labels
changelog:
exclude:
labels:
- ignore-for-release
- duplicate
- invalid
authors:
- dependabot
- dependabot[bot]
categories:
- title: Breaking Changes
labels:
- breaking-change
- breaking
- title: New Features
labels:
- enhancement
- feature
- title: Bug Fixes
labels:
- bug
- fix
- title: Dependencies
labels:
- dependencies
- title: Other Changes
labels:
- "*"
+107 -134
View File
@@ -1,181 +1,154 @@
# QBit: Webhooks
# qbit-webhooks
[![Version](https://img.shields.io/badge/version-0.1.0-blue.svg)](https://github.com/Kingsrook/qbit-webhooks)
[![License](https://img.shields.io/badge/license-GNU%20Affero%20GPL%20v3-green.svg)](https://www.gnu.org/licenses/agpl-3.0.en.html)
[![Java](https://img.shields.io/badge/java-17+-blue.svg)](https://adoptium.net/)
Outbound webhook notifications for QQQ applications.
> **Webhook Implementation for QQQ Applications - Event-Driven Integration**
**For:** QQQ developers who need to notify external systems when records change
**Status:** Stable
This QBit provides a comprehensive webhook system for QQQ applications, enabling real-time event notifications to external systems and partners.
## Why This Exists
## 🚀 What Makes QBit Webhooks Different?
Modern applications don't exist in isolation. When an order is created, you might need to notify a fulfillment system. When a user updates their profile, a CRM needs to know. Polling for changes is inefficient and adds latency.
**QBit Webhooks gives you enterprise-grade webhook capabilities** - you define your event types, configure webhook endpoints, and QBit Webhooks handles the reliable delivery, retry logic, and comprehensive logging. No more building webhook infrastructure from scratch.
This QBit sends HTTP callbacks when records are inserted, updated, or deleted. Configure endpoints, select which events to send, and the system handles delivery with retries and logging.
### ✨ Core Capabilities
## Features
- **🔗 Webhook Management**: Complete webhook endpoint and subscription management
- **📡 Event Types**: Flexible event type registration and categorization
- **🔄 Reliable Delivery**: Built-in retry logic and delivery tracking
- **📊 Comprehensive Logging**: Full audit trail of webhook events and delivery attempts
- **🎯 Event Filtering**: Subscribe to specific event types and categories
- **📦 JSON Payloads**: Structured event content with API versioning support
- **Event-Driven Delivery** - Fires on insert, update, delete operations
- **Configurable Endpoints** - Register multiple webhook URLs per table
- **Payload Customization** - Include full record, changed fields only, or custom format
- **Retry Logic** - Automatic retries with exponential backoff
- **Delivery Logging** - Track success, failures, and response codes
- **Secret Signing** - HMAC signatures for payload verification
## 🔓 Open Source & Full Control
**QBit Webhooks is 100% open source** - you have complete ownership and control:
- **💻 Your Code**: Full access to QBit Webhooks source code
- **🗄️ Your Data**: All webhook data stays in your systems
- **🏗️ Your System**: Deploy anywhere - on-premises, cloud, or hybrid
- **🔒 No Vendor Lock-in**: No external webhook services required
- **⚡ Full Customization**: Modify and extend webhook behavior to your needs
### Overview
*Note: This is one of the original QBit implementations - so, some of the mechanics of how
it is loaded and used by an application are not exactly fully defined at the time of its
creation... Please excuse any dust or not-quite-round wheels you find here!*
This QBit provides a basic implementation of webhooks to a QQQ Application.
## 🏗️ Architecture
### Technology Stack
- **Java**: Java 17+ with UTF-8 encoding
- **QQQ Framework**: Built on QQQ backend modules
- **Database**: RDBMS support through QQQ tables
- **JSON**: Structured event payloads with API versioning
### What This QBit Contains
- **Webhook Management**: Complete webhook endpoint and subscription system
- **Event Processing**: Event type registration and categorization
- **Delivery System**: Reliable webhook delivery with retry logic
- **Audit Trail**: Comprehensive logging of all webhook activities
- **Database Schema**: Five core tables for webhook management
### What This QBit Does NOT Contain
- **HTTP Client**: Uses QQQ's built-in HTTP capabilities
- **Authentication**: Relies on QQQ's security framework
- **Scheduling**: Uses QQQ's job scheduling system
- **External Services**: No third-party webhook services
## 🚀 Getting Started
## Quick Start
### Prerequisites
- **Java 17+** (required for QQQ features)
- **Maven 3.8+** (for build system)
- **QQQ Application** (this is a QBit, not a standalone application)
- QQQ application (v0.20+)
- Database backend configured
### Usage
### Installation
Add to your `pom.xml`:
#### Pom dependency
```xml
<dependency>
<groupId>com.kingsrook.qbits</groupId>
<groupId>io.qrun</groupId>
<artifactId>qbit-webhooks</artifactId>
<version>${TODO}</version>
<version>0.2.0</version>
</dependency>
```
#### Setup
##### Define the QBit
### Register the QBit
```java
WebhooksQBitProducer producer = new WebhooksQBitProducer()
.withQBitConfig(new WebhooksQBitConfig());
MetaDataProducerMultiOutput allQBitMetaData = producer.produce(qInstance);
// add it to your QInstance.
public class AppMetaProvider extends QMetaProvider {
@Override
public void configure(QInstance qInstance) {
new WebhooksQBit().configure(qInstance);
}
}
```
##### Define webhook event types
```java
WebhooksRegistry webhooksRegistry = WebhooksRegistry.ofOrWithNew(qInstance);
### Configure a Webhook
webhooksRegistry.registerWebhookEventType(new WebhookEventType()
.withName(ORDER_CREATED_EVENT_TYPE)
.withLabel("Order Created")
.withCategory(WebhookEventCategory.INSERT)
.withTableName(Order.TABLE_NAME));
```java
new QWebhookMetaData()
.withName("orderCreatedNotification")
.withTable("order")
.withEvents(WebhookEvent.INSERT)
.withUrl("https://api.example.com/webhooks/orders")
.withSecret("your-signing-secret");
```
### Provides
#### Tables
- `webhook` - a connection to a partner system, e.g., URL to post events to.
- `webhookSubscription` - which event types should be sent to a webhook.
- `webhookEvent` - table-as-queue plus log of events for sending to a subscription.
- `webhookEventContent` - storage of JSON bodies to post.
- `webhookEventSendLog` - tracking of attempted sends.
## Usage
#### Classes
- `WebhooksRegistry` - where application-defined event types must be registered.
### Multiple Events
### Dependencies
- `qqq-backend-module-api` - as the objects posted are api-versioned
- `QQQTablesMetaDataProvider` - for event record foreign keys
```java
new QWebhookMetaData()
.withName("customerSync")
.withTable("customer")
.withEvents(WebhookEvent.INSERT, WebhookEvent.UPDATE, WebhookEvent.DELETE)
.withUrl("https://crm.example.com/sync");
```
## 📚 Documentation
### Conditional Delivery
**📖 [Complete Documentation Wiki](https://github.com/Kingsrook/qqq/wiki)** - Start here for comprehensive guides
```java
// Only fire when status changes to 'approved'
new QWebhookMetaData()
.withName("approvalNotification")
.withTable("order")
.withEvents(WebhookEvent.UPDATE)
.withCondition((oldRecord, newRecord) ->
"approved".equals(newRecord.getValue("status")) &&
!"approved".equals(oldRecord.getValue("status")))
.withUrl("https://notify.example.com/approved");
```
- **[🏠 Home](https://github.com/Kingsrook/qqq/wiki/Home)** - Project overview and quick start
- **[🏗️ Architecture](https://github.com/Kingsrook/qqq/wiki/High-Level-Architecture)** - System design and principles
- **[🔧 Development](https://github.com/Kingsrook/qqq/wiki/Developer-Onboarding)** - Setup and contribution guide
- **[📦 Modules](https://github.com/Kingsrook/qqq/wiki/Core-Modules)** - Available components and usage
- **[🚀 Building](https://github.com/Kingsrook/qqq/wiki/Building-Locally)** - Local development workflow
- **[🔌 QBits](https://github.com/Kingsrook/qqq/wiki/QBit-Development)** - QBit development guide
### Custom Payload
## 🤝 Contributing
```java
new QWebhookMetaData()
.withName("slackNotification")
.withTable("alert")
.withEvents(WebhookEvent.INSERT)
.withPayloadTransformer((record) -> Map.of(
"text", "New alert: " + record.getValue("message"),
"channel", "#alerts"
))
.withUrl("https://hooks.slack.com/services/xxx");
```
QBit Webhooks is **open source** and welcomes contributions!
### Verifying Signatures
- **🐛 [Report Issues](https://github.com/Kingsrook/qqq/issues)** - Bug reports and feature requests
- **📝 [Contribution Guide](https://github.com/Kingsrook/qqq/wiki/Contribution-Guidelines)** - How to contribute code and documentation
- **🔍 [Code Standards](https://github.com/Kingsrook/qqq/wiki/Code-Review-Standards)** - QQQ's coding standards and review process
Receiving systems can verify the payload using the HMAC-SHA256 signature in the `X-Webhook-Signature` header:
**First time contributing?** Start with our [Developer Onboarding Guide](https://github.com/Kingsrook/qqq/wiki/Developer-Onboarding) to get your environment set up.
```java
String payload = requestBody;
String signature = request.getHeader("X-Webhook-Signature");
String expected = HmacUtils.hmacSha256Hex(secret, payload);
if (!expected.equals(signature)) {
throw new SecurityException("Invalid signature");
}
```
## 🏢 About Kingsrook
## Configuration
QBit Webhooks is built by **[Kingsrook](https://qrun.io)** - making engineers more productive through intelligent automation and developer tools.
The QBit creates these tables:
- **Website**: [https://qrun.io](https://qrun.io)
- **Contact**: [contact@kingsrook.com](mailto:contact@kingsrook.com)
- **GitHub**: [https://github.com/Kingsrook](https://github.com/Kingsrook)
| Table | Purpose |
|-------|---------|
| `webhook` | Webhook endpoint configurations |
| `webhook_log` | Delivery attempts and responses |
## 📄 License
### Retry Settings
This project is licensed under the **GNU Affero General Public License v3.0** - see the [LICENSE.txt](LICENSE.txt) file for details.
```java
new WebhooksQBit()
.withMaxRetries(5)
.withRetryDelayMs(1000)
.withRetryBackoffMultiplier(2.0);
```
## 🆘 Support & Community
## Project Status
### ⚠️ Important: Use Main QQQ Repository
Stable and production-ready.
**All support, issues, discussions, and community interactions should go through the main QQQ repository:**
### Roadmap
- **Main Repository**: https://github.com/Kingsrook/qqq
- **Issues**: https://github.com/Kingsrook/qqq/issues
- **Discussions**: https://github.com/Kingsrook/qqq/discussions
- **Wiki**: https://github.com/Kingsrook/qqq.wiki
- Batch delivery (group multiple events)
- Dead letter queue for failed deliveries
- Dashboard UI for webhook management
### Why This Repository Exists
## Contributing
This repository is maintained separately from the main QQQ repository to:
- **Enable independent QBit development** and versioning
- **Allow QBit-specific CI/CD** and deployment pipelines
- **Provide clear separation** between QBit components and core framework concerns
- **Support different release cycles** for QBits vs. core framework
1. Fork the repository
2. Create a feature branch
3. Run tests: `mvn clean verify`
4. Submit a pull request
### Getting Help
- **Documentation**: Check the [QQQ Wiki](https://github.com/Kingsrook/qqq.wiki)
- **Issues**: Report bugs and feature requests on [Main QQQ Issues](https://github.com/Kingsrook/qqq/issues)
- **Discussions**: Join community discussions on [Main QQQ Discussions](https://github.com/Kingsrook/qqq/discussions)
- **Questions**: Ask questions in the main QQQ repository
---
**Ready to integrate webhooks into your QQQ application?** [Get started with QBit Webhooks today!](https://github.com/Kingsrook/qqq/wiki/QBit-Development)
## License
Proprietary - QRun.IO
+2 -2
View File
@@ -26,7 +26,7 @@
<parent>
<groupId>com.kingsrook</groupId>
<artifactId>qbit-build-parent</artifactId>
<version>1.1.0</version>
<version>1.5.1</version>
</parent>
<groupId>com.kingsrook.qbits</groupId>
@@ -64,7 +64,7 @@
</scm>
<properties>
<revision>0.2.0-SNAPSHOT</revision>
<revision>0.3.0-SNAPSHOT</revision>
</properties>