-
-
Notifications
You must be signed in to change notification settings - Fork 429
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 suggest addons based on running processes #3904
Changes from 5 commits
279fcc6
990d244
056d2ac
6bb17eb
20fd530
d905cf1
e018186
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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> |
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.process</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> |
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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
<?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.process</artifactId> | ||
|
||
<name>openHAB Core :: Bundles :: Process-based Suggested Add-on Finder</name> | ||
|
||
<dependencies> | ||
<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,128 @@ | ||
/** | ||
* 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.process; | ||
|
||
import static org.openhab.core.config.discovery.addon.AddonFinderConstants.SERVICE_NAME_PROCESS; | ||
import static org.openhab.core.config.discovery.addon.AddonFinderConstants.SERVICE_TYPE_PROCESS; | ||
|
||
import java.util.Collections; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.Set; | ||
import java.util.function.Predicate; | ||
import java.util.stream.Collectors; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.core.addon.AddonDiscoveryMethod; | ||
import org.openhab.core.addon.AddonInfo; | ||
import org.openhab.core.addon.AddonMatchProperty; | ||
import org.openhab.core.config.discovery.addon.AddonFinder; | ||
import org.openhab.core.config.discovery.addon.BaseAddonFinder; | ||
import org.osgi.service.component.annotations.Activate; | ||
import org.osgi.service.component.annotations.Component; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* This is a {@link ProcessAddonFinder} for finding suggested add-ons by checking processes running | ||
* on the openHAB server. | ||
* | ||
* @author Holger Friedrich - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
@Component(service = AddonFinder.class, name = ProcessAddonFinder.SERVICE_NAME) | ||
public class ProcessAddonFinder extends BaseAddonFinder { | ||
|
||
private static final String COMMAND = "command"; | ||
|
||
public static final String SERVICE_TYPE = SERVICE_TYPE_PROCESS; | ||
public static final String SERVICE_NAME = SERVICE_NAME_PROCESS; | ||
|
||
private final Logger logger = LoggerFactory.getLogger(ProcessAddonFinder.class); | ||
|
||
@Activate | ||
public ProcessAddonFinder() { | ||
} | ||
|
||
// get list of running processes visible to openHAB, | ||
// also tries to mitigate differences on different operating systems | ||
String getProcessCommandProcess(ProcessHandle h) { | ||
Optional<String> command = h.info().command(); | ||
if (command.isPresent()) | ||
return command.get(); | ||
Optional<String[]> args = h.info().arguments(); | ||
if (!args.isPresent()) | ||
return ""; | ||
String[] argsArray = args.get(); | ||
if (argsArray.length < 1) | ||
return ""; | ||
return argsArray[0]; | ||
} | ||
|
||
@Override | ||
public Set<AddonInfo> getSuggestedAddons() { | ||
logger.trace("ProcessAddonFinder::getSuggestedAddons"); | ||
Set<AddonInfo> result = new HashSet<>(); | ||
Set<String> processList = Collections.emptySet(); | ||
try { | ||
processList = ProcessHandle.allProcesses().map(this::getProcessCommandProcess) | ||
.filter(Predicate.not(String::isEmpty)).collect(Collectors.toUnmodifiableSet()); | ||
} catch (SecurityException | UnsupportedOperationException unused) { | ||
logger.info("Cannot obtain process list, suggesting add-ons not possible"); | ||
kaikreuzer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return result; | ||
} | ||
// logging task list is commented out by default due to privacy reasons | ||
// logger.trace("Processes visible: {}", processList.toString()); | ||
holgerfriedrich marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
for (AddonInfo candidate : addonCandidates) { | ||
for (AddonDiscoveryMethod method : candidate.getDiscoveryMethods().stream() | ||
.filter(method -> SERVICE_TYPE.equals(method.getServiceType())).toList()) { | ||
|
||
List<AddonMatchProperty> matchProperties = method.getMatchProperties(); | ||
List<AddonMatchProperty> commands = matchProperties.stream() | ||
.filter(amp -> COMMAND.equals(amp.getName())).collect(Collectors.toUnmodifiableList()); | ||
|
||
if (matchProperties.size() != commands.size()) { | ||
logger.warn("Add-on '{}' addon.xml file contains unsupported 'match-property'", candidate.getUID()); | ||
} | ||
|
||
if (commands.isEmpty()) { | ||
logger.warn("Add-on '{}' addon.xml file does not specify match property \"{}\"", candidate.getUID(), | ||
COMMAND); | ||
break; | ||
} | ||
|
||
// now check if a process matches the pattern defined in addon.xml | ||
logger.debug("Checking candidate: {}", candidate.getUID()); | ||
|
||
for (AddonMatchProperty command : commands) { | ||
logger.trace("Candidate {}, pattern \"{}\"", candidate.getUID(), command.getRegex()); | ||
boolean match = processList.stream().anyMatch(c -> command.getPattern().matcher(c).matches()); | ||
|
||
if (match) { | ||
result.add(candidate); | ||
logger.debug("Suggested add-on found: {}", candidate.getUID()); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
return result; | ||
} | ||
|
||
@Override | ||
public String getServiceName() { | ||
return SERVICE_NAME; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -83,6 +83,12 @@ | |
<feature dependency="true">openhab.tp-jmdns</feature> | ||
</feature> | ||
|
||
<feature name="openhab-core-config-discovery-addon-process" version="${project.version}"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you add this feature to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think someone did already ask to have enabling/disabling. ?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For me, that's conditional. If retrieving the processes is too high a load, we should. Otherwise I don't see the point. Right now, the implementation does not cache anything and does a call to retrieve the processes any time the suggestions are retrieved. If that is quick, no need to enable/disable a little piece of code. There is nothing running in the background in separate threads either. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mherwege I am OK with that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done as suggested, just did the verification - still works |
||
<feature>openhab-core-base</feature> | ||
<feature>openhab-core-config-discovery-addon</feature> | ||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.discovery.addon.process/${project.version}</bundle> | ||
</feature> | ||
|
||
<feature name="openhab-core-config-discovery-addon-upnp" version="${project.version}"> | ||
<feature>openhab-core-base</feature> | ||
<feature>openhab-core-config-discovery-addon</feature> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can eliminate these constants from AddonFinderConstants.java and define them here instead with the same logic. Only refer to ADDON_SUGGESTION_FINDER in AddonFinderConstants.java.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...but I had to make ADDON_SUGGESTION_FINDER public...