Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cloud Events #161

Open
wants to merge 48 commits into
base: feature/CONNECTOR-134/push-sync
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
f6e7819
First draft for cloud event
rubenvdlinde Jan 9, 2025
5e6fe2f
Add the listener
rubenvdlinde Jan 9, 2025
be5d333
Add rules to open connector
rubenvdlinde Jan 11, 2025
d754763
Setting the frontend code
rubenvdlinde Jan 11, 2025
2e0fabd
More frontend work
rubenvdlinde Jan 11, 2025
7dbcef9
First bit of testing on rules
rubenvdlinde Jan 12, 2025
9f448e5
Basic frontend crud testing
rubenvdlinde Jan 12, 2025
30d4364
Lets try to add dropdowns
rubenvdlinde Jan 12, 2025
60405f9
Console error fix
rubenvdlinde Jan 12, 2025
ee597f3
Fixes from testing
rubenvdlinde Jan 12, 2025
9aaae36
Still getting the model to behave
rubenvdlinde Jan 12, 2025
f4c47ce
Last modal fixes
rubenvdlinde Jan 12, 2025
75e31a2
Merge remote-tracking branch 'origin/development' into feature/CONNEC…
rubenvdlinde Jan 12, 2025
d74bd96
Fixing the endpoint object
rubenvdlinde Jan 12, 2025
9c2d2d6
Add the tabs
rubenvdlinde Jan 12, 2025
21d1829
Add rule dialog
rubenvdlinde Jan 12, 2025
367eb1d
Fixed adding rules to endpoints
rubenvdlinde Jan 12, 2025
3f49014
Small fixed
rubenvdlinde Jan 12, 2025
76edc2b
Docs
rubenvdlinde Jan 12, 2025
58e72d8
Update the rules logic in the endpoint service
rubenvdlinde Jan 12, 2025
d682110
Let round up the rules logic
rubenvdlinde Jan 12, 2025
4f1c11e
add authentication and dowloads to ui en documentation
rubenvdlinde Jan 13, 2025
2da4454
Add upload and locking frontend
rubenvdlinde Jan 13, 2025
2ddd88e
PR review changes, incl. import&export fixes
WilcoLouwerse Jan 13, 2025
85b2975
Forgot to add findByRef for EventSubscriptionMapper & RuleMapper
WilcoLouwerse Jan 13, 2025
a220d22
Update list of objects that are not allowed to be imported/exported
WilcoLouwerse Jan 13, 2025
d0dcc21
Code style & docblock changes
WilcoLouwerse Jan 13, 2025
8e5861e
lint-fix
Sudo-Thijn Jan 13, 2025
e2448e2
Merge pull request #169 from ConductionNL/feature/CONNECTOR-134/push-…
rjzondervan Jan 13, 2025
a2f33a8
Fix routes
WilcoLouwerse Jan 13, 2025
50d7baa
added my own requested changes
Sudo-Thijn Jan 13, 2025
b91eafc
Merge remote-tracking branch 'origin/feature/CONNECTOR-52/cloud-event…
Sudo-Thijn Jan 13, 2025
397212e
Some more route fixes
WilcoLouwerse Jan 13, 2025
fd71392
Merge remote-tracking branch 'origin/feature/CONNECTOR-52/cloud-event…
WilcoLouwerse Jan 13, 2025
43d304e
Update docblocks
WilcoLouwerse Jan 14, 2025
a00195a
Merge branch 'development' into feature/CONNECTOR-52/cloud-events
WilcoLouwerse Jan 14, 2025
6a12582
Small fix for checking rule method
WilcoLouwerse Jan 14, 2025
9c16b7d
Fixes for dealing with empty responces
rubenvdlinde Jan 14, 2025
7d21c04
Fix for getting objects from the root of a responce
rubenvdlinde Jan 14, 2025
c425180
Update documentation
rubenvdlinde Jan 14, 2025
31957a6
LInting fixes
rubenvdlinde Jan 14, 2025
6d57684
Added import export on rule
remko48 Jan 14, 2025
dd57426
Merge remote-tracking branch 'origin/feature/CONNECTOR-52/cloud-event…
remko48 Jan 14, 2025
a977d7c
rule export on list
remko48 Jan 14, 2025
2b7bd86
Fix version in export filename
WilcoLouwerse Jan 14, 2025
c59d764
Merge remote-tracking branch 'origin/feature/CONNECTOR-52/cloud-event…
WilcoLouwerse Jan 14, 2025
5154bb3
Mapping hotfix
rubenvdlinde Jan 15, 2025
baeff9d
Merge branch 'feature/CONNECTOR-52/cloud-events' of https://github.co…
rubenvdlinde Jan 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
'Jobs' => ['url' => 'api/jobs'],
'Synchronizations' => ['url' => 'api/synchronizations'],
'Consumers' => ['url' => 'api/consumers'],
'Rules' => ['url' => 'api/rules'],
'Events' => ['url' => 'api/events'],
],
'routes' => [
['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'],
Expand All @@ -17,22 +19,39 @@
['name' => 'jobs#logs', 'url' => '/api/jobs-logs/{id}', 'verb' => 'GET'],
['name' => 'endpoints#test', 'url' => '/api/endpoints-test/{id}', 'verb' => 'POST'],
['name' => 'endpoints#logs', 'url' => '/api/endpoints-logs/{id}', 'verb' => 'GET'],

// Synchronization endpoints
['name' => 'synchronizations#contracts', 'url' => '/api/synchronizations-contracts/{id}', 'verb' => 'GET'],
['name' => 'synchronizations#logs', 'url' => '/api/synchronizations-logs/{id}', 'verb' => 'GET'],
['name' => 'synchronizations#test', 'url' => '/api/synchronizations-test/{id}', 'verb' => 'POST'],
['name' => 'synchronizations#run', 'url' => '/api/synchronizations-run/{id}', 'verb' => 'POST'],

// Mapping endpoints
['name' => 'mappings#test', 'url' => '/api/mappings/test', 'verb' => 'POST'],
['name' => 'mappings#saveObject', 'url' => '/api/mappings/objects', 'verb' => 'POST'],
['name' => 'mappings#getObjects', 'url' => '/api/mappings/objects', 'verb' => 'GET'],

// Running endpoints - allow any path after /api/endpoints/
['name' => 'endpoints#handlePath', 'postfix' => 'read', 'url' => '/api/endpoint/{_path}', 'verb' => 'GET', 'requirements' => ['_path' => '.+']],
['name' => 'endpoints#handlePath', 'postfix' => 'update', 'url' => '/api/endpoint/{_path}', 'verb' => 'PUT', 'requirements' => ['_path' => '.+']],
['name' => 'endpoints#handlePath', 'postfix' => 'create', 'url' => '/api/endpoint/{_path}', 'verb' => 'POST', 'requirements' => ['_path' => '.+']],
['name' => 'endpoints#handlePath', 'postfix' => 'destroy', 'url' => '/api/endpoint/{_path}', 'verb' => 'DELETE', 'requirements' => ['_path' => '.+']],

// Import & Export
['name' => 'import#import', 'url' => '/api/import', 'verb' => 'POST'],
// ['name' => 'import#importUpdate', 'url' => '/api/import/{id}', 'verb' => 'PUT'],
['name' => 'export#export', 'url' => '/api/export/{type}/{id}', 'verb' => 'GET'],

// Event messages
['name' => 'events#messages', 'url' => '/api/events/{id}/messages', 'verb' => 'GET'],

// Subscription management
['name' => 'events#subscriptions', 'url' => '/api/events/subscriptions', 'verb' => 'GET'],
['name' => 'events#subscriptionMessages', 'url' => '/api/events/subscriptions/{subscriptionId}/messages', 'verb' => 'GET'],
['name' => 'events#subscribe', 'url' => '/api/events/subscriptions', 'verb' => 'POST'],
['name' => 'events#updateSubscription', 'url' => '/api/events/subscriptions/{subscriptionId}', 'verb' => 'PUT'],
['name' => 'events#unsubscribe', 'url' => '/api/events/subscriptions/{subscriptionId}', 'verb' => 'DELETE'],

// Pull-based delivery
['name' => 'events#pull', 'url' => '/api/events/subscriptions/{subscriptionId}/pull', 'verb' => 'GET'],
],
];
77 changes: 77 additions & 0 deletions docs/Synchronization/Synchronization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Synchronization

Synchronization is a core feature that enables data transfer between different systems and APIs. Here's how it works:

## Overview
- Synchronizations define how data should be synchronized between a source and target system
- Each synchronization has a source configuration (where to get data from) and target configuration (where to send data to)
- The synchronization process handles pagination, data mapping, and maintaining sync state

## Key Components

### Source Configuration
- Defines where to fetch data from (API endpoint, database etc)
- Specifies how to map source data to target format (incomming data)
- Specifies how to locate objects in the response using resultsPosition:
- `_root`: Uses the entire response body as the objects array
- Dot notation (e.g. `data.items`): Extracts objects from a nested path
- Common keys (`items`, `result`, `results`): Automatically checks these standard locations
- Custom path: Specify any JSON path to locate the objects
- Configures pagination settings (paginationQuery)
- Can include conditions to filter which objects to sync using JSON Logic
- Source type can be set to API or other supported types
- Source ID mapping allows specifying position of IDs in source objects
- Optional endpoint configuration for fetching data

### Target Configuration
- Defines where to send synchronized data
- Specifies how to map target data to source format (outgoing data)
- Handles create/update/delete operations
- Target type can be Register/Schema or other supported types
- Target ID and schema selection for Register/Schema targets
- Target source mapping for data transformations

### Synchronization Contracts
- Tracks the sync state for each individual object
- Stores origin ID and target ID mappings
- Maintains hashes to detect changes
- Logs synchronization events and errors

## Process Flow
1. Fetch objects from source system with pagination
2. Filter objects based on configured conditions
3. Create/update synchronization contracts for each object
4. Transform data according to mapping rules
5. Write objects to target system (POST/PUT/DELETE)
6. Update contract status and hashes
7. Handle any follow-up synchronizations

## Error Handling
- Rate limiting detection and backoff
- Logging of failed operations
- Contract state tracking for retry attempts

The synchronization system provides a robust way to keep data in sync across different systems while maintaining state and handling errors gracefully.

## Form Configuration
The synchronization form allows configuring:

- Name: Descriptive name for the synchronization
- Description: Optional details about the synchronization
- Conditions: JSON Logic conditions for filtering objects
- Source Configuration:
- Source Type: API or other supported types
- Source ID: Selection of configured source
- Source hash mapping: Hash configuration
- Source target mapping: Data mapping rules
- Position of ID in source object (optional)
- Position of results in source object (optional)
- Custom endpoint for data fetching (optional)
- Target Configuration:
- Target Type: Register/Schema or other types
- Target ID: Selection of target system
- Register and Schema selection for Register/Schema targets
- Target source mapping: Data transformation rules
- Test sync option to validate configuration

![alt text](image.png)
Binary file added docs/Synchronization/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 37 additions & 5 deletions docs/cloudevents.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,44 @@

We facilitate subscriptions on a pub/sub model. This is based on [CloudEvents](https://cloudevents.io/) but also supports the [NL GOV profile for CloudEvents](https://www.logius.nl/domeinen/gegevensuitwisseling/nl-gov-profile-cloudevents). More documentation can be found [here](https://gitdocumentatie.logius.nl/publicatie/notificatieservices/CloudEvents-NL/).

## Subsribers
# Event System

## Publishers
## Event Subscriptions

## Endpoints
The OpenConnector platform implements the [CloudEvents Subscription API specification](https://github.com/cloudevents/spec/blob/main/subscriptions/spec.md) to manage event subscriptions. This allows consumers to subscribe to specific events and receive them through various delivery mechanisms.

## Mappings
### Subscription Styles

## Events
The platform supports two subscription styles:

- **Push**: Events are actively sent to the subscriber's endpoint (sink)
- **Pull**: Subscribers fetch events from the platform

### Subscription Properties

Each subscription contains the following properties:

- `id`: Unique identifier for the subscription
- `source`: URI identifying where events originate
- `types`: Array of CloudEvent type values to subscribe to
- `config`: Subscription-specific configuration
- `filters`: Array of filter expressions for event matching
- `sink`: URI where events should be delivered
- `protocol`: Delivery protocol (HTTP, MQTT, AMQP, etc.)
- `protocolSettings`: Protocol-specific settings
- `style`: Delivery style ('push' or 'pull')
- `status`: Subscription status
- `userId`: Owner of the subscription

### Filter Dialects

The platform supports the following filter dialects as defined in the CloudEvents specification:

- `exact`: Exact matching of attribute values
- `prefix`: Prefix matching of attribute values
- `suffix`: Suffix matching of attribute values
- `all`: Logical AND of multiple filters
- `any`: Logical OR of multiple filters
- `not`: Logical NOT of a filter

### Example Subscription
100 changes: 100 additions & 0 deletions docs/rules/rules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Rules

Rules are components that can be associated with endpoints to add additional functionality. Based on the current codebase, rules are stored as string IDs and can be attached to multiple endpoints.

## Adding Rules to Endpoints

Rules can be added to endpoints through the AddEndpointRule modal component. The process works as follows:

1. Select a rule from the available rule options dropdown
2. The rule ID is added to the endpoint's `rules` array property
3. The endpoint is updated with the new rule association
4. On success, the modal closes automatically after 2 seconds

## Rule Properties

Rules have several key properties that define their behavior:

- uuid: A unique identifier string for the rule
- name: The display name of the rule
- description: A detailed description of the rule's purpose
- action: Specifies when the rule triggers (create, read, update, delete)
- timing: Controls if rule runs 'before' or 'after' the action (defaults to 'before')
- conditions: JSON Logic format conditions that determine when rule applies
- type: The rule type (mapping, error, script, synchronization, authentication, download, upload, locking)
- configuration: Type-specific configuration stored as JSON
- order: Integer determining execution order when multiple rules exist

The properties work together to define:

1. When the rule executes (action + timing)
2. Under what conditions it runs (conditions)
3. What functionality it provides (type + configuration)
4. The sequence of execution (order)

Rules are stored in a structured format but referenced by endpoints using their UUID strings in an array format.

## Rule Implementation

The current implementation shows:

- Rules are managed through a dedicated API endpoint at `/api/rules`
- Rules can be retrieved and managed through the Rules resource controller
- Rule IDs are stored and validated as strings within endpoints
- The endpoint entity ensures rules are always stored as an array

## Rule Types

### Authentication Rules

Authentication rules control access to endpoints by validating user credentials and permissions. Configuration options include:

- type: The authentication method to use
- basic: Basic HTTP authentication
- jwt: JSON Web Token authentication
- jwt-zgw: ZGW-specific JWT authentication
- oauth: OAuth 2.0 authentication
- users: Array of specific users allowed to access the endpoint
- groups: Array of user groups allowed to access the endpoint

### Download Rules

Download rules handle file access and retrieval. Configuration includes:

- fileIdPosition: Specifies the position of the file ID in the URL path
- Automatic validation of user access rights to requested files

### Upload Rules

Upload rules manage file upload functionality and restrictions. Configuration includes:

- path: The target directory path for uploaded files
- allowedTypes: Comma-separated list of allowed file extensions (e.g., jpg,png,pdf)
- maxSize: Maximum allowed file size in megabytes

### Locking Rules

Locking rules provide exclusive access control for resources. Configuration includes:

- action: The locking operation to perform
- lock: Lock a resource for exclusive access
- unlock: Release a previously locked resource
- timeout: Duration in minutes before the lock automatically expires

## Rule Validation

When adding rules to an endpoint:

- The rules array is initialized if it doesn't exist
- Existing rule IDs are converted to strings
- New rule IDs are validated before being added
- The endpoint is revalidated after rule changes

## Error Handling

The rule addition process includes:

- Validation that a rule is selected before saving
- Error catching and display if the save fails
- Loading state management during the save process
- Success/error message display to the user
3 changes: 3 additions & 0 deletions lib/Controller/EndpointsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ public function destroy(int $id): JSONResponse
*/
public function handlePath(string $_path): JSONResponse
{
// @todo: move to a rule service
/*
try {
$token = $this->request->getHeader('Authorization');
$this->authorizationService->authorize(authorization: $token);
Expand All @@ -206,6 +208,7 @@ public function handlePath(string $_path): JSONResponse
statusCode: 401
);
}
*/

// Find matching endpoints for the given path and method
$matchingEndpoints = $this->endpointMapper->findByPathRegex(
Expand Down
Loading
Loading