mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-10 21:31:53 +01:00
Service to suggest addons based on running processes (#3904)
* Service to suggest addons based on running processes Signed-off-by: Holger Friedrich <mail@holger-friedrich.de>
This commit is contained in:
parent
4b92db3775
commit
4e634c6b55
@ -316,6 +316,12 @@
|
|||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
<scope>compile</scope>
|
<scope>compile</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.openhab.core.bundles</groupId>
|
||||||
|
<artifactId>org.openhab.core.config.discovery.addon.process</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openhab.core.bundles</groupId>
|
<groupId>org.openhab.core.bundles</groupId>
|
||||||
<artifactId>org.openhab.core.config.discovery.addon.upnp</artifactId>
|
<artifactId>org.openhab.core.config.discovery.addon.upnp</artifactId>
|
||||||
|
@ -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>
|
@ -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>
|
@ -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
|
||||||
|
|
@ -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>
|
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* 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.ADDON_SUGGESTION_FINDER;
|
||||||
|
|
||||||
|
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 {
|
||||||
|
|
||||||
|
public static final String SERVICE_TYPE = "process";
|
||||||
|
public static final String CFG_FINDER_PROCESS = "suggestionFinderProcess";
|
||||||
|
public static final String SERVICE_NAME = SERVICE_TYPE + ADDON_SUGGESTION_FINDER;
|
||||||
|
|
||||||
|
private static final String COMMAND = "command";
|
||||||
|
|
||||||
|
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 based on running processes is not possible");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
@ -25,7 +25,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
|||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class AddonFinderConstants {
|
public class AddonFinderConstants {
|
||||||
|
|
||||||
private static final String ADDON_SUGGESTION_FINDER = "-addon-suggestion-finder";
|
public static final String ADDON_SUGGESTION_FINDER = "-addon-suggestion-finder";
|
||||||
private static final String ADDON_SUGGESTION_FINDER_FEATURE = "openhab-core-config-discovery-addon-";
|
private static final String ADDON_SUGGESTION_FINDER_FEATURE = "openhab-core-config-discovery-addon-";
|
||||||
|
|
||||||
public static final String SERVICE_TYPE_MDNS = "mdns";
|
public static final String SERVICE_TYPE_MDNS = "mdns";
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
<module>org.openhab.core.config.discovery</module>
|
<module>org.openhab.core.config.discovery</module>
|
||||||
<module>org.openhab.core.config.discovery.addon</module>
|
<module>org.openhab.core.config.discovery.addon</module>
|
||||||
<module>org.openhab.core.config.discovery.addon.mdns</module>
|
<module>org.openhab.core.config.discovery.addon.mdns</module>
|
||||||
|
<module>org.openhab.core.config.discovery.addon.process</module>
|
||||||
<module>org.openhab.core.config.discovery.addon.upnp</module>
|
<module>org.openhab.core.config.discovery.addon.upnp</module>
|
||||||
<module>org.openhab.core.config.discovery.mdns</module>
|
<module>org.openhab.core.config.discovery.mdns</module>
|
||||||
<module>org.openhab.core.config.discovery.usbserial</module>
|
<module>org.openhab.core.config.discovery.usbserial</module>
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.automation/${project.version}</bundle>
|
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.automation/${project.version}</bundle>
|
||||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.core/${project.version}</bundle>
|
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.core/${project.version}</bundle>
|
||||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.discovery/${project.version}</bundle>
|
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.discovery/${project.version}</bundle>
|
||||||
|
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.discovery.addon.process/${project.version}</bundle>
|
||||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.dispatch/${project.version}</bundle>
|
<bundle>mvn:org.openhab.core.bundles/org.openhab.core.config.dispatch/${project.version}</bundle>
|
||||||
<bundle>mvn:org.openhab.core.bundles/org.openhab.core/${project.version}</bundle>
|
<bundle>mvn:org.openhab.core.bundles/org.openhab.core/${project.version}</bundle>
|
||||||
<bundle>mvn:org.openhab.osgiify/io.methvin.directory-watcher/0.18.0</bundle>
|
<bundle>mvn:org.openhab.osgiify/io.methvin.directory-watcher/0.18.0</bundle>
|
||||||
|
Loading…
Reference in New Issue
Block a user