Skip to content

Commit

Permalink
Service to suggest addons based on running processes (#3904)
Browse files Browse the repository at this point in the history
* Service to suggest addons based on running processes

Signed-off-by: Holger Friedrich <[email protected]>
  • Loading branch information
holgerfriedrich authored Dec 16, 2023
1 parent 4b92db3 commit 4e634c6
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 1 deletion.
6 changes: 6 additions & 0 deletions bom/openhab-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,12 @@
<version>${project.version}</version>
<scope>compile</scope>
</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>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.config.discovery.addon.upnp</artifactId>
Expand Down
29 changes: 29 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.process/.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.process/.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.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>
14 changes: 14 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.process/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

29 changes: 29 additions & 0 deletions bundles/org.openhab.core.config.discovery.addon.process/pom.xml
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,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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@NonNullByDefault
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-";

public static final String SERVICE_TYPE_MDNS = "mdns";
Expand Down
1 change: 1 addition & 0 deletions bundles/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<module>org.openhab.core.config.discovery</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.process</module>
<module>org.openhab.core.config.discovery.addon.upnp</module>
<module>org.openhab.core.config.discovery.mdns</module>
<module>org.openhab.core.config.discovery.usbserial</module>
Expand Down
1 change: 1 addition & 0 deletions features/karaf/openhab-core/src/main/feature/feature.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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.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.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/${project.version}</bundle>
<bundle>mvn:org.openhab.osgiify/io.methvin.directory-watcher/0.18.0</bundle>
Expand Down

0 comments on commit 4e634c6

Please sign in to comment.