Skip to content

Commit

Permalink
Merge pull request #83 from eclipse-thingweb/client-factories
Browse files Browse the repository at this point in the history
feat(servient): improve handling of client factories
  • Loading branch information
JKRhb authored Dec 19, 2023
2 parents 3be4625 + 568bb89 commit 6c415fe
Show file tree
Hide file tree
Showing 12 changed files with 136 additions and 30 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ import 'package:dart_wot/dart_wot.dart';
Future<void> main(List<String> args) async {
final CoapClientFactory coapClientFactory = CoapClientFactory();
final servient = Servient()..addClientFactory(coapClientFactory);
final servient = Servient(
protocolClients: [coapClientFactory]
);
final wot = await servient.start();
final thingDescriptionJson = '''
Expand Down
2 changes: 1 addition & 1 deletion example/coap_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Future<void> handleThingDescription(
}

Future<void> main(List<String> args) async {
final servient = Servient()..addClientFactory(CoapClientFactory());
final servient = Servient(clientFactories: [CoapClientFactory()]);

final wot = await servient.start();
final uri = Uri.parse('coap://plugfest.thingweb.io:5683/testthing');
Expand Down
6 changes: 5 additions & 1 deletion example/coap_dns_sd_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ void handleThingDescription(ThingDescription thingDescription) =>
print('Discovered TD with title "${thingDescription.title}".');

Future<void> main(List<String> args) async {
final servient = Servient()..addClientFactory(CoapClientFactory());
final servient = Servient(
clientFactories: [
CoapClientFactory(),
],
);

final wot = await servient.start();
final uri = Uri.parse('_wot._udp.local');
Expand Down
7 changes: 6 additions & 1 deletion example/coaps_readproperty.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ Future<void> main(List<String> args) async {
),
pskCredentialsCallback: _pskCredentialsCallback,
);
final servient = Servient()..addClientFactory(coapClientFactory);

final servient = Servient(
clientFactories: [
coapClientFactory,
],
);

final wot = await servient.start();

Expand Down
18 changes: 11 additions & 7 deletions example/complex_example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,19 @@ Future<BasicCredentials?> basicCredentialsCallback(
}

Future<void> main() async {
const coapConfig = CoapConfig(blocksize: 64);
final CoapClientFactory coapClientFactory = CoapClientFactory(
coapConfig: coapConfig,
final coapClientFactory = CoapClientFactory(
coapConfig: const CoapConfig(blocksize: 64),
);
final HttpClientFactory httpClientFactory =

final httpClientFactory =
HttpClientFactory(basicCredentialsCallback: basicCredentialsCallback);
final servient = Servient()
..addClientFactory(coapClientFactory)
..addClientFactory(httpClientFactory);

final servient = Servient(
clientFactories: [
coapClientFactory,
httpClientFactory,
],
);
final wot = await servient.start();

final thingDescription = ThingDescription(thingDescriptionJson);
Expand Down
2 changes: 1 addition & 1 deletion example/core_link_format_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const propertyName = 'status';
const actionName = 'toggle';

Future<void> main(List<String> args) async {
final servient = Servient()..addClientFactory(CoapClientFactory());
final servient = Servient(clientFactories: [CoapClientFactory()]);

final wot = await servient.start();

Expand Down
19 changes: 12 additions & 7 deletions example/example.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@ Future<BasicCredentials?> basicCredentialsCallback(
}

Future<void> main(List<String> args) async {
final CoapClientFactory coapClientFactory = CoapClientFactory();
final HttpClientFactory httpClientFactory =
final coapClientFactory = CoapClientFactory();
final httpClientFactory =
HttpClientFactory(basicCredentialsCallback: basicCredentialsCallback);
final MqttClientFactory mqttClientFactory = MqttClientFactory();
final servient = Servient()
..addClientFactory(coapClientFactory)
..addClientFactory(httpClientFactory)
..addClientFactory(mqttClientFactory);
final mqttClientFactory = MqttClientFactory();

final servient = Servient(
clientFactories: [
coapClientFactory,
httpClientFactory,
mqttClientFactory,
],
);

final wot = await servient.start();

const thingDescriptionJson = '''
Expand Down
11 changes: 8 additions & 3 deletions example/http_basic_authentication.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,14 @@ Future<BasicCredentials?> basicCredentialsCallback(
/// Illustrates the usage of both the basic and the automatic security scheme,
/// with a server supporting basic authentication.
Future<void> main(List<String> args) async {
final HttpClientFactory httpClientFactory =
HttpClientFactory(basicCredentialsCallback: basicCredentialsCallback);
final servient = Servient()..addClientFactory(httpClientFactory);
final httpClientFactory = HttpClientFactory(
basicCredentialsCallback: basicCredentialsCallback,
);
final servient = Servient(
clientFactories: [
httpClientFactory,
],
);
final wot = await servient.start();

final thingDescription = ThingDescription(thingDescriptionJson);
Expand Down
27 changes: 23 additions & 4 deletions lib/src/core/servient.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,24 @@ class ServientException implements Exception {
class Servient {
/// Creates a new [Servient].
///
/// A custom [contentSerdes] can be passed that supports other media types
/// than the default ones.
/// The [Servient] can be preconfigured with a [List] of
/// [ProtocolClientFactory]s.
/// However, it is also possible to dynamically [addClientFactory]s and
/// [removeClientFactory]s at runtime.
///
/// If you want to support a custom media type not already included in the
/// [ContentSerdes] class, a custom [contentSerdes] object can be passed as an
/// argument.
Servient({
List<ProtocolClientFactory>? clientFactories,
ServerSecurityCallback? serverSecurityCallback,
ContentSerdes? contentSerdes,
}) : contentSerdes = contentSerdes ?? ContentSerdes(),
_serverSecurityCallback = serverSecurityCallback;
_serverSecurityCallback = serverSecurityCallback {
for (final clientFactory in clientFactories ?? <ProtocolClientFactory>[]) {
addClientFactory(clientFactory);
}
}

final List<ProtocolServer> _servers = [];
final Map<String, ProtocolClientFactory> _clientFactories = {};
Expand Down Expand Up @@ -184,13 +195,21 @@ class Servient {
List<String> get clientSchemes =>
_clientFactories.keys.toList(growable: false);

/// Adds a new [clientFactory] to this [Servient.]
/// Adds a new [clientFactory] to this [Servient].
void addClientFactory(ProtocolClientFactory clientFactory) {
for (final scheme in clientFactory.schemes) {
_clientFactories[scheme] = clientFactory;
}
}

/// Removes a [ProtocolClientFactory] matching the given [scheme] from this
/// [Servient], if present.
///
/// If a [ProtocolClientFactory] was removed, the method returns it, otherwise
/// the return value is `null`.
ProtocolClientFactory? removeClientFactory(String scheme) =>
_clientFactories.remove(scheme);

/// Checks whether a [ProtocolClient] is avaiable for a given [scheme].
bool hasClientFor(String scheme) => _clientFactories.containsKey(scheme);

Expand Down
7 changes: 4 additions & 3 deletions test/binding_http/http_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,14 @@ void main() {
]) async =>
bearerCredentialsStore[uri.host];

final servient = Servient()
..addClientFactory(
final servient = Servient(
clientFactories: [
HttpClientFactory(
basicCredentialsCallback: basicCredentialsCallback,
bearerCredentialsCallback: bearerCredentialsCallback,
),
);
],
);
final wot = await servient.start();

final consumedThing = await wot.consume(parsedTd);
Expand Down
2 changes: 1 addition & 1 deletion test/core/consumed_thing_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ void main() {

final parsedTd = ThingDescription(thingDescriptionJson);

final servient = Servient()..addClientFactory(HttpClientFactory());
final servient = Servient(clientFactories: [HttpClientFactory()]);
final wot = await servient.start();

final uriVariables = {'value': 'SFRUUEJJTiBpcyBhd2Vzb21l'};
Expand Down
61 changes: 61 additions & 0 deletions test/core/servient_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2023 Contributors to the Eclipse Foundation. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// SPDX-License-Identifier: BSD-3-Clause

import 'package:dart_wot/dart_wot.dart';
import 'package:test/test.dart';

const testUriScheme = 'test';

class MockedProtocolClientFactory implements ProtocolClientFactory {
@override
ProtocolClient createClient() {
throw UnimplementedError('Instantiating a client is not supported yet.');
}

@override
bool destroy() {
return true;
}

@override
bool init() {
return true;
}

@override
Set<String> get schemes => {testUriScheme};
}

void main() {
group('Servient Tests', () {
test('Should accept a ProtocolClientFactory list as constructor argument',
() {
final servient = Servient(
clientFactories: [
MockedProtocolClientFactory(),
],
);

expect(servient.clientSchemes, [testUriScheme]);
expect(servient.hasClientFor(testUriScheme), true);
});

test(
'Should allow for adding and removing a ProtocolClientFactory at runtime',
() {
final servient = Servient()
..addClientFactory(MockedProtocolClientFactory());

expect(servient.hasClientFor(testUriScheme), true);

servient.removeClientFactory(testUriScheme);

expect(servient.hasClientFor(testUriScheme), false);
expect(servient.clientSchemes.length, 0);
},
);
});
}

0 comments on commit 6c415fe

Please sign in to comment.