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

Service to find suggested addons to install #3806

Merged
merged 99 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
99 commits
Select commit Hold shift + click to select a range
a304edd
[suggestion-finder] initial contribution
andrewfg Sep 17, 2023
5350ba2
[suggestion-finder] tweaks
andrewfg Sep 17, 2023
547d0b1
[suggestion-finder] spotless
andrewfg Sep 17, 2023
f9e9da3
[suggestion-finder] second attempt
andrewfg Sep 18, 2023
8f8cab3
[suggestion-finder] typo
andrewfg Sep 18, 2023
f497728
[suggestion-finder] refactoring
andrewfg Sep 18, 2023
db37288
[suggestion-finder] fix modelName property
andrewfg Sep 18, 2023
25952fd
[suggestion-finder] add servlet, and javadocs
andrewfg Sep 18, 2023
69bfdb3
[suggestion-finder] move servlet to rest api; refactoring
andrewfg Sep 19, 2023
3c1f6a2
[suggestion-finder] refactoring
andrewfg Sep 19, 2023
4d63b5d
[suggestion-finder] spotless
andrewfg Sep 19, 2023
bb6261a
[suggestion-finder] spotless
andrewfg Sep 19, 2023
75bb0f4
[suggestion-finder] implement AddonService
andrewfg Sep 19, 2023
9bfcb0d
[suggestion-finder] tweaks
andrewfg Sep 19, 2023
9132a4e
[suggestion-finder] schema; xml resource; itests
andrewfg Sep 20, 2023
e90266f
[suggestion-finder] better logging
andrewfg Sep 20, 2023
24fbaa3
[suggestion-finder] various tweaks
andrewfg Sep 21, 2023
5c5b9a9
[suggestion-finder] fix some dependencies
andrewfg Sep 22, 2023
3cd54a7
[suggestion-finder] fix some dependencies
andrewfg Oct 11, 2023
a993d6c
[suggestion-finder] delete xsd file
andrewfg Oct 11, 2023
3f89f03
[suggestion-finder] change osgi tst to junit test
andrewfg Oct 12, 2023
85775fe
[suggestion-finder] convert finders to osgi
andrewfg Oct 13, 2023
19d5058
[suggestion-finder] split interface from base class
andrewfg Oct 13, 2023
37bef62
[suggestion-finder] add java doc; allow task cancel
andrewfg Oct 14, 2023
e2eeca6
[suggestion-finder] java doc tweaks
andrewfg Oct 14, 2023
735bdf5
[suggestion-finder] xsd schema and dto
andrewfg Oct 17, 2023
e98a429
[suggestion-finder] adapt for special addon
andrewfg Oct 20, 2023
2eb632f
[suggestion-finder] update xml schema, converters, and tests
andrewfg Oct 21, 2023
dd4c29a
[suggested addon finder] refactoring
andrewfg Oct 23, 2023
753aa2e
[suggested addon finder] refactoring
andrewfg Oct 25, 2023
1715463
[suggested addon finder] adopt reviewer suggestions
andrewfg Oct 26, 2023
481c764
[suggested addon finder] merge addonInfo's
andrewfg Oct 26, 2023
12e2c91
[suggested addon finder] adopt reviewer suggestion
andrewfg Oct 26, 2023
9d86372
[suggested addon finder] fix javadoc; fix enrichment
andrewfg Oct 27, 2023
5b331c0
[suggested addon finder] add equals(), hash()
andrewfg Oct 27, 2023
636d4ce
[suggested addon finder] remove uid
andrewfg Oct 27, 2023
ff8f484
[suggested addon finder] fix getAddonInfo(), mergeAddonInfos()
andrewfg Oct 27, 2023
1011efa
[suggested addon finder] add .filter(Objects::nonNull)
andrewfg Oct 27, 2023
614c3a2
[suggested addon finder] add JUnit test for merging
andrewfg Oct 27, 2023
3108edc
[suggested addon finder] refactor junits tests
andrewfg Oct 28, 2023
5c71da1
[suggested addon finder] serviceId merge and tests
andrewfg Oct 28, 2023
729806b
[suggested addon finder] compile pattern on first use
andrewfg Oct 29, 2023
535c80e
[suggested addon finder] fix memory leak; add trace logging
andrewfg Oct 30, 2023
987f3db
[suggested addon finder] improve logging, null checks, matching
andrewfg Oct 30, 2023
679ec1b
[suggested addon finder] quick fixes for reviewer
andrewfg Oct 31, 2023
2dfe987
[suggested addon finder] update candidates on load
andrewfg Oct 31, 2023
632ae4a
[suggested addon finder] fix check for null properties
andrewfg Oct 31, 2023
e600579
[suggested addon finder] works in progress
andrewfg Nov 1, 2023
e466240
[suggested addon finder] remove trace logging
andrewfg Nov 2, 2023
e32a0d7
[suggested addon finder] performance tweaks
andrewfg Nov 4, 2023
2160dd3
[suggested addon finder] fix test
andrewfg Nov 4, 2023
a939627
[addon suggestion finder] move addoninfo changes into second PR
andrewfg Nov 6, 2023
56a3a5b
[addon suggestion finder] align PR contents
andrewfg Nov 6, 2023
968ec3a
[addon suggestion finder] add means to disable finders
andrewfg Nov 7, 2023
5716c84
[addon suggestion finder] fix osgi timing issue
andrewfg Nov 9, 2023
7cda061
[addon suggestion finder] add configuration to OSGI methods
andrewfg Nov 11, 2023
d8ee432
[addon suggestion finder] fully qualify config name
andrewfg Nov 11, 2023
8504776
[addon suggestion finder] reduce logging aggressivity
andrewfg Nov 11, 2023
71f4214
[addon suggestion finder] adopt reviewer suggestion
andrewfg Nov 21, 2023
be30e56
[addon suggestion finder] adopt reviewer suggestion
andrewfg Nov 23, 2023
1d671bf
[addoninfo] core extensions
andrewfg Nov 6, 2023
7533795
[addoninfo] remove addon installer; add code to core
andrewfg Nov 8, 2023
7829136
[addoninfo] fix path name
andrewfg Nov 8, 2023
4fb6329
[addoninfo] xml schemas
andrewfg Nov 8, 2023
ab40acb
[addoninfo] xml schemas (again)
andrewfg Nov 9, 2023
2d483b6
[addoninfo] update AddonsInfoProvider
andrewfg Nov 9, 2023
db7c583
finders karaf feature install
mherwege Nov 20, 2023
a9e1599
[addon-suggestion-finder] resolve merge conflict
andrewfg Dec 3, 2023
073d003
[addon-suggestion-finder] fix SAT error
andrewfg Dec 3, 2023
7f10099
Update bundles/org.openhab.core.config.discovery.addon.mdns/src/main/…
andrewfg Dec 5, 2023
b7d1c62
Update bundles/org.openhab.core.config.discovery.addon/src/main/java/…
andrewfg Dec 5, 2023
393a4bf
Update bundles/org.openhab.core.config.discovery.addon/src/main/java/…
andrewfg Dec 5, 2023
a0c3450
Update bundles/org.openhab.core.config.discovery.addon/src/main/java/…
andrewfg Dec 5, 2023
c6ec7c5
Update bundles/org.openhab.core.config.discovery.addon/src/main/java/…
andrewfg Dec 5, 2023
7b5e913
Update bundles/org.openhab.core.config.discovery.addon/src/main/java/…
andrewfg Dec 5, 2023
5d12a3f
[addon-suggestion-finder] adopt reviwer suggestions
andrewfg Dec 5, 2023
25c64e8
[addon-suggestion-finder] fix git rename bug part 1
andrewfg Dec 5, 2023
e9facf7
[addon-suggestion-finder] fix git rename bug part 2
andrewfg Dec 5, 2023
2ceb3a9
[addoninfo] core extensions
andrewfg Nov 6, 2023
bde4ace
[addoninfo] remove addon installer; add code to core
andrewfg Nov 8, 2023
7f6851b
[addoninfo] fix path name
andrewfg Nov 8, 2023
52520a5
[addoninfo] xml schemas
andrewfg Nov 8, 2023
6316c89
[addoninfo] xml schemas (again)
andrewfg Nov 9, 2023
0837bd1
[addoninfo] update AddonsInfoProvider
andrewfg Nov 9, 2023
59c8197
[addoninfp] adopt reviewer suggestions
andrewfg Nov 23, 2023
94ba401
[addonInfo extensions] adopt reviewer suggestions
andrewfg Dec 5, 2023
a34a156
[addonInfo extensions] adopt reviewer suggestions
andrewfg Dec 5, 2023
a0a9878
[addon-suggestion-finder] add notice
andrewfg Dec 6, 2023
5ffd0c2
[AddonInfoAddonsXmlProvider] fix issue #3901
andrewfg Dec 6, 2023
932ba87
Merge branch 'fix-3901' into binding-finder
andrewfg Dec 6, 2023
d57af01
Revert "[AddonInfoAddonsXmlProvider] fix issue #3901"
andrewfg Dec 7, 2023
34f5cd5
Update bundles/org.openhab.core.config.discovery.addon.mdns/src/main/…
andrewfg Dec 7, 2023
ed6a0fe
Update bundles/org.openhab.core.config.discovery.addon.upnp/src/main/…
andrewfg Dec 7, 2023
0433221
Update bundles/org.openhab.core.config.discovery.addon/src/main/java/…
andrewfg Dec 7, 2023
67996a2
Update bundles/org.openhab.core/src/main/resources/OH-INF/config/addo…
andrewfg Dec 7, 2023
67e0a78
Update bundles/org.openhab.core/src/main/resources/OH-INF/config/addo…
andrewfg Dec 7, 2023
da454f3
[addon-suggestion-finder] adopt (some of) reviewer suggestions
andrewfg Dec 7, 2023
eb03f06
[addon-suggestion-finder] adapt to ongoing discussion
andrewfg Dec 7, 2023
59b099c
[addon-suggestion-finder] tweak java doc
andrewfg Dec 7, 2023
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
18 changes: 18 additions & 0 deletions bom/openhab-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,24 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.addon</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.addon.mdns</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.addon.upnp</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.mdns</artifactId>
Expand Down
29 changes: 29 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.mdns/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-17">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="annotationpath" value="target/dependency"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="annotationpath" value="target/dependency"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
23 changes: 23 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.mdns/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.openhab.core.config.discovery.addon.mdns</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
14 changes: 14 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.mdns/NOTICE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
This content is produced and maintained by the openHAB project.

* Project home: https://www.openhab.org

== Declared Project Licenses

This program and the accompanying materials are made available under the terms
of the Eclipse Public License 2.0 which is available at
https://www.eclipse.org/legal/epl-2.0/.

== Source Code

https://github.com/openhab/openhab-core

34 changes: 34 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.mdns/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.reactor.bundles</artifactId>
<version>4.1.0-SNAPSHOT</version>
</parent>

<artifactId>org.openhab.core.config.discovery.addon.mdns</artifactId>

<name>openHAB Core :: Bundles :: mDNS Suggested Add-on Finder</name>

<dependencies>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.mdns</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.addon</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.addon</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.core.config.discovery.addon.mdns;

import static org.openhab.core.config.discovery.addon.AddonFinderConstants.SERVICE_NAME_MDNS;
import static org.openhab.core.config.discovery.addon.AddonFinderConstants.SERVICE_TYPE_MDNS;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import javax.jmdns.ServiceEvent;
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.addon.AddonDiscoveryMethod;
import org.openhab.core.addon.AddonInfo;
import org.openhab.core.common.ThreadPoolManager;
import org.openhab.core.config.discovery.addon.AddonFinder;
import org.openhab.core.config.discovery.addon.BaseAddonFinder;
import org.openhab.core.io.transport.mdns.MDNSClient;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This is a {@link MDNSAddonFinder} for finding suggested add-ons via mDNS.
*
* @author Andrew Fiddian-Green - Initial contribution
* @author Mark Herwege - refactor to allow uninstall
*/
@NonNullByDefault
@Component(service = AddonFinder.class, name = MDNSAddonFinder.SERVICE_NAME)
public class MDNSAddonFinder extends BaseAddonFinder implements ServiceListener {

public static final String SERVICE_TYPE = SERVICE_TYPE_MDNS;
public static final String SERVICE_NAME = SERVICE_NAME_MDNS;

private static final String NAME = "name";
private static final String APPLICATION = "application";

private final Logger logger = LoggerFactory.getLogger(MDNSAddonFinder.class);
private final ScheduledExecutorService scheduler = ThreadPoolManager.getScheduledPool(SERVICE_NAME);
private final Map<String, ServiceInfo> services = new ConcurrentHashMap<>();
private MDNSClient mdnsClient;

@Activate
public MDNSAddonFinder(@Reference MDNSClient mdnsClient) {
this.mdnsClient = mdnsClient;
}

/**
* Adds the given mDNS service to the set of discovered services.
*
* @param device the mDNS service to be added.
*/
public void addService(ServiceInfo service, boolean isResolved) {
String qualifiedName = service.getQualifiedName();
if (isResolved || !services.containsKey(qualifiedName)) {
if (services.put(qualifiedName, service) == null) {
logger.trace("Added service: {}", qualifiedName);
}
}
}

@Deactivate
public void deactivate() {
services.clear();
unsetAddonCandidates();
}

@Override
public void setAddonCandidates(List<AddonInfo> candidates) {
// Remove listeners for all service types that are no longer in candidates
addonCandidates.stream().filter(c -> !candidates.contains(c))
.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType()))
.filter(m -> !m.getMdnsServiceType().isEmpty())
.forEach(m -> mdnsClient.removeServiceListener(m.getMdnsServiceType(), this)));

// Add listeners for all service types in candidates
super.setAddonCandidates(candidates);
addonCandidates
.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType()))
.filter(m -> !m.getMdnsServiceType().isEmpty()).forEach(m -> {
String serviceType = m.getMdnsServiceType();
mdnsClient.addServiceListener(serviceType, this);
scheduler.submit(() -> mdnsClient.list(serviceType));
}));
}

@Override
public void unsetAddonCandidates() {
addonCandidates.forEach(c -> c.getDiscoveryMethods().stream()
.filter(m -> SERVICE_TYPE.equals(m.getServiceType())).filter(m -> !m.getMdnsServiceType().isEmpty())
.forEach(m -> mdnsClient.removeServiceListener(m.getMdnsServiceType(), this)));
super.unsetAddonCandidates();
}

@Override
public Set<AddonInfo> getSuggestedAddons() {
Set<AddonInfo> result = new HashSet<>();
for (AddonInfo candidate : addonCandidates) {
for (AddonDiscoveryMethod method : candidate.getDiscoveryMethods().stream()
.filter(method -> SERVICE_TYPE.equals(method.getServiceType())).toList()) {
Map<String, Pattern> matchProperties = method.getMatchProperties().stream()
.collect(Collectors.toMap(property -> property.getName(), property -> property.getPattern()));

Set<String> matchPropertyKeys = matchProperties.keySet().stream()
.filter(property -> (!NAME.equals(property) && !APPLICATION.equals(property)))
.collect(Collectors.toSet());

logger.trace("Checking candidate: {}", candidate.getUID());
for (ServiceInfo service : services.values()) {

logger.trace("Checking service: {}/{}", service.getQualifiedName(), service.getNiceTextString());
if (method.getMdnsServiceType().equals(service.getType())
&& propertyMatches(matchProperties, NAME, service.getName())
&& propertyMatches(matchProperties, APPLICATION, service.getApplication())
&& matchPropertyKeys.stream().allMatch(
name -> propertyMatches(matchProperties, name, service.getPropertyString(name)))) {
result.add(candidate);
logger.debug("Suggested add-on found: {}", candidate.getUID());
break;
}
}
}
}
return result;
}

@Override
public String getServiceName() {
return SERVICE_NAME;
}

/*
* ************ MDNSClient call-back methods ************
*/

@Override
public void serviceAdded(@Nullable ServiceEvent event) {
if (event != null) {
ServiceInfo service = event.getInfo();
if (service != null) {
addService(service, false);
}
}
}

@Override
public void serviceRemoved(@Nullable ServiceEvent event) {
}

@Override
public void serviceResolved(@Nullable ServiceEvent event) {
if (event != null) {
ServiceInfo service = event.getInfo();
if (service != null) {
addService(service, true);
}
}
}
}
Loading