Skip to content

Commit

Permalink
Merge pull request #180 from eclipse-thingweb/discovery-configuration
Browse files Browse the repository at this point in the history
feat!: move discovery configurations to scripting_api package
  • Loading branch information
JKRhb authored Jun 7, 2024
2 parents 0191f0d + bcac81f commit 8a182a6
Show file tree
Hide file tree
Showing 11 changed files with 111 additions and 90 deletions.
15 changes: 8 additions & 7 deletions example/coap_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,19 @@ Future<void> handleThingDescription(
Future<void> main(List<String> args) async {
final servient = Servient.create(
clientFactories: [CoapClientFactory()],
discoveryConfigurations: [
DirectConfiguration(
Uri.parse("coap://plugfest.thingweb.io:5683/testthing"),
),
],
);

final wot = await servient.start();
final discoveryConfigurations = [
DirectConfiguration(
Uri.parse("coap://plugfest.thingweb.io:5683/testthing"),
),
];

// Example using for-await-loop
try {
await for (final thingDescription in wot.discover()) {
await for (final thingDescription
in wot.discover(discoveryConfigurations)) {
await handleThingDescription(wot, thingDescription);
}
print('Discovery with "await for" has finished.');
Expand All @@ -62,7 +63,7 @@ Future<void> main(List<String> args) async {
//
// Notice how the "onDone" callback is called before the result is passed
// to the handleThingDescription function.
wot.discover().listen(
wot.discover(discoveryConfigurations).listen(
(thingDescription) async {
await handleThingDescription(wot, thingDescription);
},
Expand Down
12 changes: 7 additions & 5 deletions example/coap_dns_sd_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,18 @@ Future<void> main(List<String> args) async {
CoapClientFactory(),
HttpClientFactory(),
],
discoveryConfigurations: [
const DnsSdDConfiguration(protocolType: ProtocolType.udp),
],
);

final wot = await servient.start();

final discoveryConfigurations = [
const DnsSdDConfiguration(protocolType: ProtocolType.udp),
];

// Example using for-await-loop
try {
await for (final thingDescription in wot.discover()) {
await for (final thingDescription
in wot.discover(discoveryConfigurations)) {
handleThingDescription(thingDescription);
}
print('Discovery with "await for" has finished.');
Expand All @@ -40,7 +42,7 @@ Future<void> main(List<String> args) async {
//
// Notice how the "onDone" callback is called before the result is passed
// to the handleThingDescription function.
wot.discover().listen(
wot.discover(discoveryConfigurations).listen(
handleThingDescription,
onError: (error) => print("Encountered an error: $error"),
onDone: () => print('Discovery with "listen" has finished.'),
Expand Down
12 changes: 6 additions & 6 deletions example/core_link_format_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import "package:dart_wot/core.dart";
Future<void> main(List<String> args) async {
final servient = Servient.create(
clientFactories: [CoapClientFactory()],
discoveryConfigurations: [
CoreLinkFormatConfiguration(
Uri.parse("coap://plugfest.thingweb.io"),
),
],
);

final wot = await servient.start();
final discoveryConfigurations = [
CoreLinkFormatConfiguration(
Uri.parse("coap://plugfest.thingweb.io"),
),
];

await for (final thingDescription in wot.discover()) {
await for (final thingDescription in wot.discover(discoveryConfigurations)) {
print(thingDescription.title);

if (thingDescription.title != "Smart-Coffee-Machine") {
Expand Down
1 change: 0 additions & 1 deletion lib/src/core/implementation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,4 @@ export "implementation/augmented_form.dart";
export "implementation/codecs/content_codec.dart";
export "implementation/content.dart";
export "implementation/content_serdes.dart";
export "implementation/discovery/discovery_configuration.dart";
export "implementation/servient.dart" show Servient;
27 changes: 5 additions & 22 deletions lib/src/core/implementation/servient.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import "../scripting_api.dart" as scripting_api;

import "consumed_thing.dart";
import "content_serdes.dart";
import "discovery/discovery_configuration.dart";
import "exposed_thing.dart";
import "thing_discovery.dart";
import "wot.dart";
Expand All @@ -28,8 +27,7 @@ import "wot.dart";
abstract class Servient {
/// Creates a new [Servient].
///
/// The [Servient] can be pre-configured with [List]s of
/// [clientFactories] and [discoveryConfigurations].
/// The [Servient] can be pre-configured with a [List] of [clientFactories].
/// However, it is also possible to dynamically [addClientFactory]s and
/// [removeClientFactory]s at runtime.
///
Expand All @@ -40,24 +38,14 @@ abstract class Servient {
List<ProtocolClientFactory>? clientFactories,
ServerSecurityCallback? serverSecurityCallback,
ContentSerdes? contentSerdes,
List<DiscoveryConfiguration>? discoveryConfigurations,
}) {
return InternalServient(
clientFactories: clientFactories,
serverSecurityCallback: serverSecurityCallback,
contentSerdes: contentSerdes,
discoveryConfigurations: discoveryConfigurations,
);
}

/// [List] of [DiscoveryConfiguration]s that are used when calling the
/// [scripting_api.WoT.discover] method.
List<DiscoveryConfiguration> get discoveryConfigurations;

set discoveryConfigurations(
List<DiscoveryConfiguration> discoveryConfigurations,
);

/// Starts this [Servient] and returns a [scripting_api.WoT] runtime object.
///
/// The [scripting_api.WoT] runtime can be used for consuming, producing, and
Expand Down Expand Up @@ -85,9 +73,7 @@ class InternalServient implements Servient {
List<ProtocolClientFactory>? clientFactories,
ServerSecurityCallback? serverSecurityCallback,
ContentSerdes? contentSerdes,
List<DiscoveryConfiguration>? discoveryConfigurations,
}) : contentSerdes = contentSerdes ?? ContentSerdes(),
discoveryConfigurations = discoveryConfigurations ?? [],
_serverSecurityCallback = serverSecurityCallback {
for (final clientFactory in clientFactories ?? <ProtocolClientFactory>[]) {
addClientFactory(clientFactory);
Expand All @@ -100,9 +86,6 @@ class InternalServient implements Servient {

final ServerSecurityCallback? _serverSecurityCallback;

@override
List<DiscoveryConfiguration> discoveryConfigurations;

/// The [ContentSerdes] object that is used for serializing/deserializing.
final ContentSerdes contentSerdes;

Expand Down Expand Up @@ -343,15 +326,15 @@ class InternalServient implements Servient {
return thingDescription;
}

/// Perform automatic discovery using this [InternalServient]'s
/// [discoveryConfigurations].
/// Perform discovery using the passed-in [discoveryConfigurations].
///
/// A [thingFilter] can be provided to filter the discovered Thing
/// Descriptions; however, doing so currently does not have any effect yet.
ThingDiscovery discover({
ThingDiscovery discover(
List<scripting_api.DiscoveryConfiguration> discoveryConfigurations, {
scripting_api.ThingFilter? thingFilter,
}) {
return ThingDiscovery(thingFilter, this);
return ThingDiscovery(thingFilter, this, discoveryConfigurations);
}

/// Requests a [ThingDescription] from a [url].
Expand Down
38 changes: 23 additions & 15 deletions lib/src/core/implementation/thing_discovery.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,17 @@ import "../protocol_interfaces.dart";
import "../scripting_api.dart" as scripting_api;

import "content.dart";
import "discovery/discovery_configuration.dart";
import "servient.dart";

/// Implementation of the [scripting_api.ThingDiscovery] interface.
class ThingDiscovery extends Stream<ThingDescription>
implements scripting_api.ThingDiscovery {
/// Creates a new [ThingDiscovery] object with a given [thingFilter].
ThingDiscovery(this.thingFilter, this._servient) {
ThingDiscovery(
this.thingFilter,
this._servient,
this._discoveryConfigurations,
) {
_stream = _start();
}

Expand All @@ -42,40 +45,45 @@ class ThingDiscovery extends Stream<ThingDescription>
@override
final scripting_api.ThingFilter? thingFilter;

final List<scripting_api.DiscoveryConfiguration> _discoveryConfigurations;

late final Stream<ThingDescription> _stream;

Stream<ThingDescription> _start() async* {
for (final discoveryParameter in _servient.discoveryConfigurations) {
for (final discoveryParameter in _discoveryConfigurations) {
switch (discoveryParameter) {
case DnsSdDConfiguration(
case scripting_api.DnsSdDConfiguration(
:final discoveryType,
domainName: final domain,
:final protocolType,
):
yield* _discoverUsingDnsSd(discoveryType, domain, protocolType);
case CoreLinkFormatConfiguration(
case scripting_api.CoreLinkFormatConfiguration(
:final uri,
:final discoveryType,
):
yield* _discoverWithCoreLinkFormat(uri, discoveryType);
case CoreResourceDirectoryConfiguration(
case scripting_api.CoreResourceDirectoryConfiguration(
:final uri,
:final discoveryType,
):
yield* _discoverFromCoreResourceDirectory(uri, discoveryType);
case DirectConfiguration(:final uri):
case scripting_api.DirectConfiguration(:final uri):
if (!uri.hasMulticastAddress) {
yield* Stream.fromFuture(_servient.requestThingDescription(uri));
} else {
yield* _performMulticastDiscovery(uri);
}
case ExploreDirectoryConfiguration(:final uri, :final thingFilter):
case scripting_api.ExploreDirectoryConfiguration(
:final uri,
:final thingFilter
):
final thingDiscoveryProcess = await _servient.exploreDirectory(
uri,
thingFilter: thingFilter,
);
yield* thingDiscoveryProcess;
case MqttDiscoveryConfiguration(
case scripting_api.MqttDiscoveryConfiguration(
:final brokerUri,
:final discoveryTopic,
:final expectedContentType,
Expand Down Expand Up @@ -122,9 +130,9 @@ class ThingDiscovery extends Stream<ThingDescription>
}

Stream<ThingDescription> _discoverUsingDnsSd(
DiscoveryType discoveryType,
scripting_api.DiscoveryType discoveryType,
String domainName,
ProtocolType protocolType,
scripting_api.ProtocolType protocolType,
) async* {
if (domainName != ".local") {
throw UnimplementedError(
Expand All @@ -134,7 +142,7 @@ class ThingDiscovery extends Stream<ThingDescription>

final serviceNameSegments = <String>[];

if (discoveryType == DiscoveryType.directory) {
if (discoveryType == scripting_api.DiscoveryType.directory) {
serviceNameSegments.addAll(const ["_directory", "_sub"]);
}

Expand All @@ -155,7 +163,7 @@ class ThingDiscovery extends Stream<ThingDescription>
Stream<ThingDescription> _performMdnsDiscovery(
String domainName,
String defaultUriScheme,
DiscoveryType expectedType,
scripting_api.DiscoveryType expectedType,
) async* {
final MDnsClient client = MDnsClient();
await client.start();
Expand Down Expand Up @@ -233,7 +241,7 @@ class ThingDiscovery extends Stream<ThingDescription>

Stream<ThingDescription> _discoverWithCoreLinkFormat(
Uri uri,
DiscoveryType discoveryType,
scripting_api.DiscoveryType discoveryType,
) async* {
await for (final coreWebLinks in _performCoreLinkFormatDiscovery(
uri,
Expand All @@ -246,7 +254,7 @@ class ThingDiscovery extends Stream<ThingDescription>

Stream<ThingDescription> _discoverFromCoreResourceDirectory(
Uri uri,
DiscoveryType discoveryType,
scripting_api.DiscoveryType discoveryType,
) async* {
yield* _performCoreLinkFormatDiscovery(
uri,
Expand Down
11 changes: 9 additions & 2 deletions lib/src/core/implementation/wot.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

import "dart:async";

import "package:meta/meta.dart";

import "../definitions.dart";
import "../scripting_api.dart" as scripting_api;
import "consumed_thing.dart";
Expand Down Expand Up @@ -39,10 +41,15 @@ class WoT implements scripting_api.WoT {
_servient.produce(init);

@override
ThingDiscovery discover({
ThingDiscovery discover(
@experimental
List<scripting_api.DiscoveryConfiguration> discoveryConfigurations, {
scripting_api.ThingFilter? thingFilter,
}) =>
_servient.discover(thingFilter: thingFilter);
_servient.discover(
discoveryConfigurations,
thingFilter: thingFilter,
);

@override
Future<ThingDescription> requestThingDescription(Uri url) =>
Expand Down
2 changes: 2 additions & 0 deletions lib/src/core/scripting_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ library scripting_api;

export "scripting_api/consumed_thing.dart";
export "scripting_api/data_schema_value.dart";
export "scripting_api/discovery/directory_payload_format.dart";
export "scripting_api/discovery/discovery_configuration.dart";
export "scripting_api/discovery/thing_discovery.dart";
export "scripting_api/discovery/thing_filter.dart";
export "scripting_api/exposed_thing.dart";
Expand Down
34 changes: 34 additions & 0 deletions lib/src/core/scripting_api/discovery/directory_payload_format.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2024 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

/// Enumeration for specifying the value of the `format` query parameter when
/// using the `exploreDirectory` discovery method.
///
/// See [section 7.3.2.1.5] of the [WoT Discovery] specification for more
/// information.
///
/// [WoT Discovery]: https://www.w3.org/TR/2023/REC-wot-discovery-20231205
/// [section 7.3.2.1.5]: https://www.w3.org/TR/2023/REC-wot-discovery-20231205/#exploration-directory-api-things-listing
enum DirectoryPayloadFormat {
/// Indicates that an array of Thing Descriptions should be returned.
///
/// This is the default value.
array,

/// Indicates that an collection of Thing Descriptions should be returned.
collection,
;

@override
String toString() {
switch (this) {
case array:
return "array";
case collection:
return "collection";
}
}
}
Loading

0 comments on commit 8a182a6

Please sign in to comment.