Skip to content
This repository was archived by the owner on Jul 25, 2022. It is now read-only.

Commit 3d450d2

Browse files
authored
Merge pull request #10 from LukasPoque/add_s3i_event_system
Add S3I Event System
2 parents 7fc697a + ba26fd6 commit 3d450d2

17 files changed

+781
-73
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## 0.5.0
2+
3+
Add S3I Event System functionality:
4+
5+
- EventMessage, EventSubscriptionRequest, EventSubscriptionReply
6+
- `POST` and `DELETE` methods for the S3I-Config-API
7+
- Methods to create/remove normal and event broker endpoints (queues)
8+
- Method to configure the `ActiveBrokerInterfaces` to be used as an event broker
9+
- `EventSystemConnector` - a class to simplify the subscription to custom/named events
10+
111
## 0.4.1
212

313
Fix utf8 encoding problems.

README.md

+55-4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,56 @@ Please see [pub.dev](https://pub.dev/packages/s3i_flutter/install) for instructi
4747
If you like this package, consider supporting it by giving a star on [GitHub](https://github.com/LukasPoque/s3i_flutter) and
4848
a like on [pub.dev](https://pub.dev/packages/s3i_flutter) :heart:
4949

50+
## Features
51+
52+
The goal for `Version 1.0.0` is to cover the important endpoints of the main S³I components and provide useful data classes to wrap the JSON-data. For `Version 2.0.0` there should be more functionality to work with the data classes, especially with the (F)ML4.0 language.
53+
54+
#### Roadmap to Version 1.0.0
55+
56+
- Authentication
57+
- [x] Authenticate an user via the S3I-OAuthProxy
58+
- [x] Use an refresh/offline token for less user interaction during authentication
59+
- [ ] Enable saving the refresh/offline token for authentication after a restart or offline
60+
- [ ] Authenticate an user via default OpenId-Connect (with redirect url)
61+
62+
- Directory
63+
- [x] Provide basic PUT/GET/DELETE request methods
64+
- [x] Request a single thing (with filter options)
65+
- [x] Modify a single thing
66+
- [x] Request a policy entry
67+
- [x] Modify a policy entry
68+
- [ ] Query the directory via thing search
69+
- [ ] Find the owner of a thing
70+
- [ ] Find all things that belongs to a specific person
71+
- [ ] Create/delete a new thing in the S³I (adds a basic thing entry to the directory and creates a client in the identity provider)
72+
73+
- Repository
74+
- [ ] Provide basic PUT/GET/DELETE request methods
75+
- [ ] Request a single thing (with filter options)
76+
- [ ] Modify a single thing
77+
- [ ] Request a policy entry
78+
- [ ] Modify a policy entry
79+
- [ ] Query the repository via thing search
80+
- [ ] Create/delete a new thing entry in the repository
81+
- [ ] Receive live updates from the cloud copy of a thing
82+
- [ ] Send live updates to the cloud copy of a thing
83+
84+
- Messaging
85+
- [x] Create/delete a new broker queue (bound to the direct exchange)
86+
- [x] Receive/send messages using AMQP (not usable for web)
87+
- [x] Receive/sent messages using the REST endpoint of the S3I-Broker-API
88+
- [x] Work with UserMessages
89+
- [x] Work with ServiceMessages
90+
- [x] Work with GetValueMessages
91+
- [ ] Work with SetValueMessages
92+
- [ ] Work with DeleteAttributeMessages
93+
- [ ] Work with CreateAttributeMessages
94+
- [x] Work with messages from the EventSystem
95+
- [x] Create/delete broker queues for the EventSystem
96+
- [x] Simple to use wrapper for the EventSystem (as a subscriber)
97+
- [ ] Helper functions for the EventSystem as publisher
98+
99+
50100
## Usage
51101

52102
For a basic example application see the [example](https://github.com/LukasPoque/s3i_flutter/tree/master/example).
@@ -175,7 +225,7 @@ brokerConnector.subscribeServiceReplyReceived((ServiceReply msg) {
175225
});
176226
```
177227

178-
If all callback you're interested in are registered it's time to start consuming on one (or multiple) queues on the S3I-Broker.
228+
If all callbacks you're interested in are registered it's time to start consuming on one (or multiple) queues on the S3I-Broker.
179229
For that simply call `startConsuming`. If you don't want any open connections left when your app closes, call `stopConsuming` with the same endpoint
180230
in your dispose method.
181231
```dart
@@ -205,7 +255,7 @@ brokerConnector.sendMessage(requestMsg, <String>{'<SERVICE ENDPOINT>'});
205255

206256
The package is divided in domain specific folders.
207257

208-
TODO: ...
258+
The `S3ICore` uses this classes and provides methods to access the REST-APIs easier.
209259

210260
### Auth
211261

@@ -231,8 +281,9 @@ At the moment, there are only active broker interfaces implemented:
231281

232282
Currently the following message types are supported:
233283
- `UserMessage`: used for communication between two real users.
234-
- `ServiceMessage`: used to invoke service functions or receive service answers from S3I-Services.
235-
- `GetValueMessage`: used to get a specific value from an other thing.
284+
- `ServiceMessages`: used to invoke service functions or receive service answers from S3I-Services.
285+
- `GetValueMessages`: used to get a specific value from an other thing.
286+
- `EventSystemMessages`: used to receive/subscribe to events via the [S3I-Event-System](https://github.com/LukasPoque/s3i_flutter/issues/9#issuecomment-925665563).
236287

237288
### Directory
238289

example/pubspec.lock

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ packages:
77
name: async
88
url: "https://pub.dartlang.org"
99
source: hosted
10-
version: "2.6.1"
10+
version: "2.8.1"
1111
boolean_selector:
1212
dependency: transitive
1313
description:
@@ -28,7 +28,7 @@ packages:
2828
name: charcode
2929
url: "https://pub.dartlang.org"
3030
source: hosted
31-
version: "1.2.0"
31+
version: "1.3.1"
3232
clock:
3333
dependency: transitive
3434
description:
@@ -120,7 +120,7 @@ packages:
120120
name: meta
121121
url: "https://pub.dartlang.org"
122122
source: hosted
123-
version: "1.3.0"
123+
version: "1.7.0"
124124
path:
125125
dependency: transitive
126126
description:
@@ -148,7 +148,7 @@ packages:
148148
path: ".."
149149
relative: true
150150
source: path
151-
version: "0.4.0"
151+
version: "0.5.0"
152152
sky_engine:
153153
dependency: transitive
154154
description: flutter
@@ -195,7 +195,7 @@ packages:
195195
name: test_api
196196
url: "https://pub.dartlang.org"
197197
source: hosted
198-
version: "0.3.0"
198+
version: "0.4.2"
199199
typed_data:
200200
dependency: transitive
201201
description:

lib/s3i_flutter.dart

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ export 'src/auth/oauth_proxy_flow.dart';
77
export 'src/auth/tokens.dart';
88

99
//broker
10-
export 'src/broker/attribute_value_messages.dart';
10+
export 'src/broker/broker_amqp_connector.dart'
11+
if (dart.library.js) 'src/broker/broker_rest_connector.dart';
1112
export 'src/broker/broker_interfaces.dart';
12-
export 'src/broker/broker_rest_connector.dart'
13-
if (dart.library.io) 'src/broker/broker_amqp_connector.dart';
14-
export 'src/broker/service_messages.dart';
15-
export 'src/broker/user_message.dart';
13+
export 'src/broker/messages/attribute_value_messages.dart';
14+
export 'src/broker/messages/service_messages.dart';
15+
export 'src/broker/messages/user_message.dart';
1616

1717
//directory
1818
export 'src/directory/dir_object.dart';

lib/src/broker/broker_amqp_connector.dart

+54-13
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:dart_amqp/dart_amqp.dart';
44
import 'package:s3i_flutter/src/auth/authentication_manager.dart';
55
import 'package:s3i_flutter/src/auth/tokens.dart';
66
import 'package:s3i_flutter/src/broker/broker_interfaces.dart';
7-
import 'package:s3i_flutter/src/broker/message.dart';
7+
import 'package:s3i_flutter/src/broker/messages/message.dart';
88
import 'package:s3i_flutter/src/exceptions/network_authentication_exception.dart';
99
import 'package:s3i_flutter/src/exceptions/s3i_exception.dart';
1010

@@ -15,6 +15,16 @@ import 'package:s3i_flutter/src/exceptions/s3i_exception.dart';
1515
/// parameters).
1616
///
1717
/// This is needed to use the same interface on web and other platforms.
18+
///
19+
/// The [args] have defaults for the normal message communication in the S3I:
20+
/// - brokerHost = 'rabbitmq.s3i.vswf.dev',
21+
/// - port = 5672,
22+
/// - virtualHost = 's3i',
23+
/// - maxConnectionAttempts = 3,
24+
/// - reconnectWaitTime = const Duration(milliseconds: 1500),
25+
/// - prefetchCount = -1,
26+
/// - exchangeName = 'demo.direct',
27+
/// - exchangeType = ExchangeType.DIRECT
1828
ActiveBrokerInterface getActiveBrokerDefaultConnector(
1929
AuthenticationManager authManager,
2030
{Map<String, dynamic> args = const <String, dynamic>{}}) {
@@ -25,14 +35,33 @@ ActiveBrokerInterface getActiveBrokerDefaultConnector(
2535
final int maxConnectionAttempts = args['maxConnectionAttempts'] as int? ?? 3;
2636
final Duration reconnectWaitTime = args['reconnectWaitTime'] as Duration? ??
2737
const Duration(milliseconds: 1500);
38+
final int prefetchCount = args['prefetchCount'] as int? ?? -1;
2839
final String exchangeName = args['exchangeName'] as String? ?? 'demo.direct';
40+
final ExchangeType exchangeType =
41+
args['exchangeType'] as ExchangeType? ?? ExchangeType.DIRECT;
42+
2943
return BrokerAmqpConnector(authManager,
3044
brokerHost: brokerHost,
3145
port: port,
3246
virtualHost: virtualHost,
3347
maxConnectionAttempts: maxConnectionAttempts,
3448
reconnectWaitTime: reconnectWaitTime,
35-
exchangeName: exchangeName);
49+
prefetchCount: prefetchCount,
50+
exchangeName: exchangeName,
51+
exchangeType: exchangeType);
52+
}
53+
54+
/// Creates a new [BrokerAmqpConnector] configured to be used for the
55+
/// Event System.
56+
///
57+
/// See [getActiveBrokerDefaultConnector] for more information.
58+
ActiveBrokerInterface getActiveBrokerEventConnector(
59+
AuthenticationManager authManager,
60+
{Map<String, dynamic> args = const <String, dynamic>{}}) {
61+
if (args.containsKey('exchangeName')) args['exchangeName'] = 'eventExchange';
62+
if (args.containsKey('exchangeType'))
63+
args['exchangeType'] = ExchangeType.TOPIC;
64+
return getActiveBrokerDefaultConnector(authManager, args: args);
3665
}
3766

3867
/// This [ActiveBrokerInterface] implementation uses the native messaging
@@ -45,16 +74,15 @@ ActiveBrokerInterface getActiveBrokerDefaultConnector(
4574
class BrokerAmqpConnector extends ActiveBrokerInterface {
4675
/// Creates a [BrokerAmqpConnector] which uses the [authManager] to receive
4776
/// tokens.
48-
///
49-
/// Unless you know what you are doing, don't change the default values
50-
/// of the named parameters.
5177
BrokerAmqpConnector(AuthenticationManager authManager,
52-
{this.brokerHost = 'rabbitmq.s3i.vswf.dev',
53-
this.port = 5672,
54-
this.virtualHost = 's3i',
55-
this.maxConnectionAttempts = 3,
56-
this.reconnectWaitTime = const Duration(milliseconds: 1500),
57-
this.exchangeName = 'demo.direct'})
78+
{required this.brokerHost,
79+
required this.port,
80+
required this.virtualHost,
81+
required this.maxConnectionAttempts,
82+
required this.reconnectWaitTime,
83+
required this.prefetchCount,
84+
required this.exchangeName,
85+
required this.exchangeType})
5886
: super(authManager);
5987

6088
/// The host to connect to.
@@ -72,9 +100,19 @@ class BrokerAmqpConnector extends ActiveBrokerInterface {
72100
/// The time between each reconnect attempt.
73101
final Duration reconnectWaitTime;
74102

103+
/// The number of messages loaded to the client without ACK.
104+
///
105+
/// If this number is < 0 no prefetch count is set => infinite prefetch.
106+
final int prefetchCount;
107+
75108
/// The name of the amqp broker exchange.
76109
final String exchangeName;
77110

111+
/// The type of the exchange, see
112+
/// [here](https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchanges)
113+
/// for more information.
114+
final ExchangeType exchangeType;
115+
78116
/// Stores all endpoints and their consumer queues.
79117
final Map<String, Consumer> _endpointConsumer = <String, Consumer>{};
80118

@@ -215,8 +253,11 @@ class BrokerAmqpConnector extends ActiveBrokerInterface {
215253
if (_amqpClient == null) throw S3IException('amqp client is null');
216254
try {
217255
_channel = await _amqpClient!.channel();
218-
_exchange = await _channel!
219-
.exchange(exchangeName, ExchangeType.DIRECT, passive: true);
256+
if (prefetchCount >= 0) {
257+
_channel = await _channel!.qos(null, prefetchCount);
258+
}
259+
_exchange =
260+
await _channel!.exchange(exchangeName, exchangeType, passive: true);
220261
} on Exception catch (e) {
221262
throw S3IException('amqp package error: $e');
222263
}

0 commit comments

Comments
 (0)