Modified finder discovery schema to make future finders easier to create (#3924)
* change discovery method schema Signed-off-by: Mark Herwege <mark.herwege@telenet.be>pull/3926/head
parent
4e634c6b55
commit
fe242f8ab9
|
@ -90,11 +90,24 @@
|
||||||
<xs:complexType name="discoveryMethodType">
|
<xs:complexType name="discoveryMethodType">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element type="xs:string" name="service-type"/>
|
<xs:element type="xs:string" name="service-type"/>
|
||||||
<xs:element type="xs:string" name="mdns-service-type" minOccurs="0"/>
|
<xs:element type="addon:ParametersType" name="discovery-parameters" minOccurs="0"/>
|
||||||
<xs:element type="addon:matchPropertiesType" name="match-properties" minOccurs="0"/>
|
<xs:element type="addon:matchPropertiesType" name="match-properties" minOccurs="0"/>
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="ParametersType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element type="addon:parameterType" name="discovery-parameter" maxOccurs="unbounded"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="parameterType">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element type="xs:string" name="name"/>
|
||||||
|
<xs:element type="xs:string" name="value"/>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
<xs:complexType name="matchPropertiesType">
|
<xs:complexType name="matchPropertiesType">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element type="addon:matchPropertyType" name="match-property" maxOccurs="unbounded"/>
|
<xs:element type="addon:matchPropertyType" name="match-property" maxOccurs="unbounded"/>
|
||||||
|
|
|
@ -26,16 +26,16 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class AddonDiscoveryMethod {
|
public class AddonDiscoveryMethod {
|
||||||
private @NonNullByDefault({}) String serviceType;
|
private @NonNullByDefault({}) String serviceType;
|
||||||
private @Nullable String mdnsServiceType;
|
private @Nullable List<AddonParameter> parameters;
|
||||||
private @Nullable List<AddonMatchProperty> matchProperties;
|
private @Nullable List<AddonMatchProperty> matchProperties;
|
||||||
|
|
||||||
public String getServiceType() {
|
public String getServiceType() {
|
||||||
return serviceType.toLowerCase();
|
return serviceType.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMdnsServiceType() {
|
public List<AddonParameter> getParameters() {
|
||||||
String mdnsServiceType = this.mdnsServiceType;
|
List<AddonParameter> parameters = this.parameters;
|
||||||
return mdnsServiceType != null ? mdnsServiceType : "";
|
return parameters != null ? parameters : List.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AddonMatchProperty> getMatchProperties() {
|
public List<AddonMatchProperty> getMatchProperties() {
|
||||||
|
@ -48,8 +48,8 @@ public class AddonDiscoveryMethod {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AddonDiscoveryMethod setMdnsServiceType(@Nullable String mdnsServiceType) {
|
public AddonDiscoveryMethod setParameters(@Nullable List<AddonParameter> parameters) {
|
||||||
this.mdnsServiceType = mdnsServiceType;
|
this.parameters = parameters;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ public class AddonDiscoveryMethod {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(serviceType, mdnsServiceType, matchProperties);
|
return Objects.hash(serviceType, parameters, matchProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -75,7 +75,7 @@ public class AddonDiscoveryMethod {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
AddonDiscoveryMethod other = (AddonDiscoveryMethod) obj;
|
AddonDiscoveryMethod other = (AddonDiscoveryMethod) obj;
|
||||||
return Objects.equals(serviceType, other.serviceType) && Objects.equals(mdnsServiceType, other.mdnsServiceType)
|
return Objects.equals(serviceType, other.serviceType) && Objects.equals(parameters, other.parameters)
|
||||||
&& Objects.equals(matchProperties, other.matchProperties);
|
&& Objects.equals(matchProperties, other.matchProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* 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.addon;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO for serialization of a add-on discovery parameter.
|
||||||
|
*
|
||||||
|
* @author Mark Herwege - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class AddonParameter {
|
||||||
|
private @NonNullByDefault({}) String name;
|
||||||
|
private @NonNullByDefault({}) String value;
|
||||||
|
|
||||||
|
public AddonParameter(String name, String value) {
|
||||||
|
this.name = name;
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return Objects.hash(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
AddonParameter other = (AddonParameter) obj;
|
||||||
|
return Objects.equals(name, other.name) && Objects.equals(value, other.value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.addon.AddonDiscoveryMethod;
|
import org.openhab.core.addon.AddonDiscoveryMethod;
|
||||||
import org.openhab.core.addon.AddonMatchProperty;
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
import org.openhab.core.config.core.xml.util.GenericUnmarshaller;
|
import org.openhab.core.config.core.xml.util.GenericUnmarshaller;
|
||||||
import org.openhab.core.config.core.xml.util.NodeIterator;
|
import org.openhab.core.config.core.xml.util.NodeIterator;
|
||||||
|
|
||||||
|
@ -46,16 +47,18 @@ public class AddonDiscoveryMethodConverter extends GenericUnmarshaller<AddonDisc
|
||||||
String serviceType = requireNonEmpty((String) nodeIterator.nextValue("service-type", true),
|
String serviceType = requireNonEmpty((String) nodeIterator.nextValue("service-type", true),
|
||||||
"Service type is null or empty");
|
"Service type is null or empty");
|
||||||
|
|
||||||
String mdnsServiceType = (String) nodeIterator.nextValue("mdns-service-type", false);
|
Object paramObject = nodeIterator.nextList("discovery-parameters", false);
|
||||||
|
List<AddonParameter> parameters = !(paramObject instanceof List<?> list) ? null
|
||||||
|
: list.stream().filter(e -> (e instanceof AddonParameter)).map(e -> ((AddonParameter) e)).toList();
|
||||||
|
|
||||||
Object object = nodeIterator.nextList("match-properties", false);
|
Object matchPropObject = nodeIterator.nextList("match-properties", false);
|
||||||
List<AddonMatchProperty> matchProperties = !(object instanceof List<?> list) ? null
|
List<AddonMatchProperty> matchProperties = !(matchPropObject instanceof List<?> list) ? null
|
||||||
: list.stream().filter(e -> (e instanceof AddonMatchProperty)).map(e -> ((AddonMatchProperty) e))
|
: list.stream().filter(e -> (e instanceof AddonMatchProperty)).map(e -> ((AddonMatchProperty) e))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
nodeIterator.assertEndOfType();
|
nodeIterator.assertEndOfType();
|
||||||
|
|
||||||
return new AddonDiscoveryMethod().setServiceType(serviceType).setMdnsServiceType(mdnsServiceType)
|
return new AddonDiscoveryMethod().setServiceType(serviceType).setParameters(parameters)
|
||||||
.setMatchProperties(matchProperties);
|
.setMatchProperties(matchProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.core.addon.AddonDiscoveryMethod;
|
import org.openhab.core.addon.AddonDiscoveryMethod;
|
||||||
import org.openhab.core.addon.AddonInfoList;
|
import org.openhab.core.addon.AddonInfoList;
|
||||||
import org.openhab.core.addon.AddonMatchProperty;
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
import org.openhab.core.config.core.ConfigDescription;
|
import org.openhab.core.config.core.ConfigDescription;
|
||||||
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
||||||
import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
|
import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
|
||||||
|
@ -69,6 +70,7 @@ public class AddonInfoListReader extends XmlDocumentReader<AddonInfoList> {
|
||||||
xstream.registerConverter(new ConfigDescriptionParameterGroupConverter());
|
xstream.registerConverter(new ConfigDescriptionParameterGroupConverter());
|
||||||
xstream.registerConverter(new FilterCriteriaConverter());
|
xstream.registerConverter(new FilterCriteriaConverter());
|
||||||
xstream.registerConverter(new AddonDiscoveryMethodConverter());
|
xstream.registerConverter(new AddonDiscoveryMethodConverter());
|
||||||
|
xstream.registerConverter(new AddonParameterConverter());
|
||||||
xstream.registerConverter(new AddonMatchPropertyConverter());
|
xstream.registerConverter(new AddonMatchPropertyConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,9 +96,11 @@ public class AddonInfoListReader extends XmlDocumentReader<AddonInfoList> {
|
||||||
xstream.alias("discovery-methods", NodeList.class);
|
xstream.alias("discovery-methods", NodeList.class);
|
||||||
xstream.alias("discovery-method", AddonDiscoveryMethod.class);
|
xstream.alias("discovery-method", AddonDiscoveryMethod.class);
|
||||||
xstream.alias("service-type", NodeValue.class);
|
xstream.alias("service-type", NodeValue.class);
|
||||||
xstream.alias("mdns-service-type", NodeValue.class);
|
xstream.alias("discovery-parameters", NodeList.class);
|
||||||
|
xstream.alias("discovery-parameter", AddonParameter.class);
|
||||||
xstream.alias("match-properties", NodeList.class);
|
xstream.alias("match-properties", NodeList.class);
|
||||||
xstream.alias("match-property", AddonMatchProperty.class);
|
xstream.alias("match-property", AddonMatchProperty.class);
|
||||||
|
xstream.alias("value", NodeValue.class);
|
||||||
xstream.alias("regex", NodeValue.class);
|
xstream.alias("regex", NodeValue.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import java.util.List;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.core.addon.AddonDiscoveryMethod;
|
import org.openhab.core.addon.AddonDiscoveryMethod;
|
||||||
import org.openhab.core.addon.AddonMatchProperty;
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
import org.openhab.core.config.core.ConfigDescription;
|
import org.openhab.core.config.core.ConfigDescription;
|
||||||
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
||||||
import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
|
import org.openhab.core.config.core.ConfigDescriptionParameterGroup;
|
||||||
|
@ -70,6 +71,7 @@ public class AddonInfoReader extends XmlDocumentReader<AddonInfoXmlResult> {
|
||||||
xstream.registerConverter(new ConfigDescriptionParameterGroupConverter());
|
xstream.registerConverter(new ConfigDescriptionParameterGroupConverter());
|
||||||
xstream.registerConverter(new FilterCriteriaConverter());
|
xstream.registerConverter(new FilterCriteriaConverter());
|
||||||
xstream.registerConverter(new AddonDiscoveryMethodConverter());
|
xstream.registerConverter(new AddonDiscoveryMethodConverter());
|
||||||
|
xstream.registerConverter(new AddonParameterConverter());
|
||||||
xstream.registerConverter(new AddonMatchPropertyConverter());
|
xstream.registerConverter(new AddonMatchPropertyConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,9 +95,11 @@ public class AddonInfoReader extends XmlDocumentReader<AddonInfoXmlResult> {
|
||||||
xstream.alias("discovery-methods", NodeList.class);
|
xstream.alias("discovery-methods", NodeList.class);
|
||||||
xstream.alias("discovery-method", AddonDiscoveryMethod.class);
|
xstream.alias("discovery-method", AddonDiscoveryMethod.class);
|
||||||
xstream.alias("service-type", NodeValue.class);
|
xstream.alias("service-type", NodeValue.class);
|
||||||
xstream.alias("mdns-service-type", NodeValue.class);
|
xstream.alias("discovery-parameters", NodeList.class);
|
||||||
|
xstream.alias("discovery-parameter", AddonParameter.class);
|
||||||
xstream.alias("match-properties", NodeList.class);
|
xstream.alias("match-properties", NodeList.class);
|
||||||
xstream.alias("match-property", AddonMatchProperty.class);
|
xstream.alias("match-property", AddonMatchProperty.class);
|
||||||
|
xstream.alias("value", NodeValue.class);
|
||||||
xstream.alias("regex", NodeValue.class);
|
xstream.alias("regex", NodeValue.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/**
|
||||||
|
* 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.addon.internal.xml;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
|
import org.openhab.core.config.core.xml.util.GenericUnmarshaller;
|
||||||
|
import org.openhab.core.config.core.xml.util.NodeIterator;
|
||||||
|
|
||||||
|
import com.thoughtworks.xstream.converters.UnmarshallingContext;
|
||||||
|
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link AddonParameterConverter} is a concrete implementation of the {@code XStream} {@link Converter}
|
||||||
|
* interface used to convert add-on discovery method parameter information within an XML document into a
|
||||||
|
* {@link AddonMatchProperty} object.
|
||||||
|
*
|
||||||
|
* @author Mark Herwege - Initial contribution
|
||||||
|
*/
|
||||||
|
@NonNullByDefault
|
||||||
|
public class AddonParameterConverter extends GenericUnmarshaller<AddonParameter> {
|
||||||
|
|
||||||
|
public AddonParameterConverter() {
|
||||||
|
super(AddonParameter.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext context) {
|
||||||
|
List<?> nodes = (List<?>) context.convertAnother(context, List.class);
|
||||||
|
NodeIterator nodeIterator = new NodeIterator(nodes);
|
||||||
|
|
||||||
|
String name = requireNonEmpty((String) nodeIterator.nextValue("name", true), "Name is null or empty");
|
||||||
|
String value = requireNonEmpty((String) nodeIterator.nextValue("value", true), "Value is null or empty");
|
||||||
|
|
||||||
|
nodeIterator.assertEndOfType();
|
||||||
|
|
||||||
|
return new AddonParameter(name, value);
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,10 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.core.addon;
|
package org.openhab.core.addon;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -44,7 +41,12 @@ class AddonInfoListReaderTest {
|
||||||
+ " <discovery-methods>"
|
+ " <discovery-methods>"
|
||||||
+ " <discovery-method>"
|
+ " <discovery-method>"
|
||||||
+ " <service-type>mdns</service-type>"
|
+ " <service-type>mdns</service-type>"
|
||||||
+ " <mdns-service-type>_printer._tcp.local.</mdns-service-type>"
|
+ " <discovery-parameters>"
|
||||||
|
+ " <discovery-parameter>"
|
||||||
|
+ " <name>mdnsServiceType</name>"
|
||||||
|
+ " <value>_printer._tcp.local.</value>"
|
||||||
|
+ " </discovery-parameter>"
|
||||||
|
+ " </discovery-parameters>"
|
||||||
+ " <match-properties>"
|
+ " <match-properties>"
|
||||||
+ " <match-property>"
|
+ " <match-property>"
|
||||||
+ " <name>rp</name>"
|
+ " <name>rp</name>"
|
||||||
|
@ -91,7 +93,13 @@ class AddonInfoListReaderTest {
|
||||||
AddonDiscoveryMethod method = discoveryMethods.get(0);
|
AddonDiscoveryMethod method = discoveryMethods.get(0);
|
||||||
assertNotNull(method);
|
assertNotNull(method);
|
||||||
assertEquals("mdns", method.getServiceType());
|
assertEquals("mdns", method.getServiceType());
|
||||||
assertEquals("_printer._tcp.local.", method.getMdnsServiceType());
|
List<AddonParameter> parameters = method.getParameters();
|
||||||
|
assertNotNull(parameters);
|
||||||
|
assertEquals(1, parameters.size());
|
||||||
|
AddonParameter parameter = parameters.get(0);
|
||||||
|
assertNotNull(parameter);
|
||||||
|
assertEquals("mdnsServiceType", parameter.getName());
|
||||||
|
assertEquals("_printer._tcp.local.", parameter.getValue());
|
||||||
List<AddonMatchProperty> matchProperties = method.getMatchProperties();
|
List<AddonMatchProperty> matchProperties = method.getMatchProperties();
|
||||||
assertNotNull(matchProperties);
|
assertNotNull(matchProperties);
|
||||||
assertEquals(2, matchProperties.size());
|
assertEquals(2, matchProperties.size());
|
||||||
|
@ -104,7 +112,9 @@ class AddonInfoListReaderTest {
|
||||||
method = discoveryMethods.get(1);
|
method = discoveryMethods.get(1);
|
||||||
assertNotNull(method);
|
assertNotNull(method);
|
||||||
assertEquals("upnp", method.getServiceType());
|
assertEquals("upnp", method.getServiceType());
|
||||||
assertEquals("", method.getMdnsServiceType());
|
parameters = method.getParameters();
|
||||||
|
assertNotNull(parameters);
|
||||||
|
assertEquals(0, parameters.size());
|
||||||
matchProperties = method.getMatchProperties();
|
matchProperties = method.getMatchProperties();
|
||||||
assertNotNull(matchProperties);
|
assertNotNull(matchProperties);
|
||||||
assertEquals(1, matchProperties.size());
|
assertEquals(1, matchProperties.size());
|
||||||
|
|
|
@ -12,16 +12,9 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.core.addon;
|
package org.openhab.core.addon;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.mockito.Mockito.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
@ -67,7 +60,7 @@ class AddonInfoRegistryMergeTest {
|
||||||
|
|
||||||
private AddonInfoProvider createAddonInfoProvider1() {
|
private AddonInfoProvider createAddonInfoProvider1() {
|
||||||
AddonDiscoveryMethod discoveryMethod = new AddonDiscoveryMethod().setServiceType("mdns")
|
AddonDiscoveryMethod discoveryMethod = new AddonDiscoveryMethod().setServiceType("mdns")
|
||||||
.setMdnsServiceType("_hue._tcp.local.");
|
.setParameters(List.of(new AddonParameter("mdnsServiceType", "_hue._tcp.local.")));
|
||||||
AddonInfo addonInfo = AddonInfo.builder("hue", "binding").withName("name-one")
|
AddonInfo addonInfo = AddonInfo.builder("hue", "binding").withName("name-one")
|
||||||
.withDescription("description-one").withCountries("GB,NL").withConnection("local")
|
.withDescription("description-one").withCountries("GB,NL").withConnection("local")
|
||||||
.withDiscoveryMethods(List.of(discoveryMethod)).build();
|
.withDiscoveryMethods(List.of(discoveryMethod)).build();
|
||||||
|
|
|
@ -12,8 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.core.config.discovery.addon.mdns;
|
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.*;
|
||||||
import static org.openhab.core.config.discovery.addon.AddonFinderConstants.SERVICE_TYPE_MDNS;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -44,10 +43,12 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a {@link MDNSAddonFinder} for finding suggested add-ons via mDNS.
|
* This is a {@link MDNSAddonFinder} for finding suggested add-ons via mDNS. This finder requires a
|
||||||
|
* {@code mdnsServiceType} parameter to be present in the add-on info discovery method.
|
||||||
*
|
*
|
||||||
* @author Andrew Fiddian-Green - Initial contribution
|
* @author Andrew Fiddian-Green - Initial contribution
|
||||||
* @author Mark Herwege - refactor to allow uninstall
|
* @author Mark Herwege - refactor to allow uninstall
|
||||||
|
* @author Mark Herwege - change to discovery method schema
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
@Component(service = AddonFinder.class, name = MDNSAddonFinder.SERVICE_NAME)
|
@Component(service = AddonFinder.class, name = MDNSAddonFinder.SERVICE_NAME)
|
||||||
|
@ -56,6 +57,8 @@ public class MDNSAddonFinder extends BaseAddonFinder implements ServiceListener
|
||||||
public static final String SERVICE_TYPE = SERVICE_TYPE_MDNS;
|
public static final String SERVICE_TYPE = SERVICE_TYPE_MDNS;
|
||||||
public static final String SERVICE_NAME = SERVICE_NAME_MDNS;
|
public static final String SERVICE_NAME = SERVICE_NAME_MDNS;
|
||||||
|
|
||||||
|
public static final String MDNS_SERVICE_TYPE = "mdnsServiceType";
|
||||||
|
|
||||||
private static final String NAME = "name";
|
private static final String NAME = "name";
|
||||||
private static final String APPLICATION = "application";
|
private static final String APPLICATION = "application";
|
||||||
|
|
||||||
|
@ -94,15 +97,15 @@ public class MDNSAddonFinder extends BaseAddonFinder implements ServiceListener
|
||||||
// Remove listeners for all service types that are no longer in candidates
|
// Remove listeners for all service types that are no longer in candidates
|
||||||
addonCandidates.stream().filter(c -> !candidates.contains(c))
|
addonCandidates.stream().filter(c -> !candidates.contains(c))
|
||||||
.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType()))
|
.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType()))
|
||||||
.filter(m -> !m.getMdnsServiceType().isEmpty())
|
.filter(m -> !getMdnsServiceType(m).isEmpty())
|
||||||
.forEach(m -> mdnsClient.removeServiceListener(m.getMdnsServiceType(), this)));
|
.forEach(m -> mdnsClient.removeServiceListener(getMdnsServiceType(m), this)));
|
||||||
|
|
||||||
// Add listeners for all service types in candidates
|
// Add listeners for all service types in candidates
|
||||||
super.setAddonCandidates(candidates);
|
super.setAddonCandidates(candidates);
|
||||||
addonCandidates
|
addonCandidates
|
||||||
.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType()))
|
.forEach(c -> c.getDiscoveryMethods().stream().filter(m -> SERVICE_TYPE.equals(m.getServiceType()))
|
||||||
.filter(m -> !m.getMdnsServiceType().isEmpty()).forEach(m -> {
|
.filter(m -> !getMdnsServiceType(m).isEmpty()).forEach(m -> {
|
||||||
String serviceType = m.getMdnsServiceType();
|
String serviceType = getMdnsServiceType(m);
|
||||||
mdnsClient.addServiceListener(serviceType, this);
|
mdnsClient.addServiceListener(serviceType, this);
|
||||||
scheduler.submit(() -> mdnsClient.list(serviceType));
|
scheduler.submit(() -> mdnsClient.list(serviceType));
|
||||||
}));
|
}));
|
||||||
|
@ -111,8 +114,8 @@ public class MDNSAddonFinder extends BaseAddonFinder implements ServiceListener
|
||||||
@Override
|
@Override
|
||||||
public void unsetAddonCandidates() {
|
public void unsetAddonCandidates() {
|
||||||
addonCandidates.forEach(c -> c.getDiscoveryMethods().stream()
|
addonCandidates.forEach(c -> c.getDiscoveryMethods().stream()
|
||||||
.filter(m -> SERVICE_TYPE.equals(m.getServiceType())).filter(m -> !m.getMdnsServiceType().isEmpty())
|
.filter(m -> SERVICE_TYPE.equals(m.getServiceType())).filter(m -> !getMdnsServiceType(m).isEmpty())
|
||||||
.forEach(m -> mdnsClient.removeServiceListener(m.getMdnsServiceType(), this)));
|
.forEach(m -> mdnsClient.removeServiceListener(getMdnsServiceType(m), this)));
|
||||||
super.unsetAddonCandidates();
|
super.unsetAddonCandidates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,7 +136,7 @@ public class MDNSAddonFinder extends BaseAddonFinder implements ServiceListener
|
||||||
for (ServiceInfo service : services.values()) {
|
for (ServiceInfo service : services.values()) {
|
||||||
|
|
||||||
logger.trace("Checking service: {}/{}", service.getQualifiedName(), service.getNiceTextString());
|
logger.trace("Checking service: {}/{}", service.getQualifiedName(), service.getNiceTextString());
|
||||||
if (method.getMdnsServiceType().equals(service.getType())
|
if (getMdnsServiceType(method).equals(service.getType())
|
||||||
&& propertyMatches(matchProperties, NAME, service.getName())
|
&& propertyMatches(matchProperties, NAME, service.getName())
|
||||||
&& propertyMatches(matchProperties, APPLICATION, service.getApplication())
|
&& propertyMatches(matchProperties, APPLICATION, service.getApplication())
|
||||||
&& matchPropertyKeys.stream().allMatch(
|
&& matchPropertyKeys.stream().allMatch(
|
||||||
|
@ -148,6 +151,12 @@ public class MDNSAddonFinder extends BaseAddonFinder implements ServiceListener
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getMdnsServiceType(AddonDiscoveryMethod method) {
|
||||||
|
String param = method.getParameters().stream().filter(p -> MDNS_SERVICE_TYPE.equals(p.getName()))
|
||||||
|
.map(p -> p.getValue()).findFirst().orElse("");
|
||||||
|
return param == null ? "" : param;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getServiceName() {
|
public String getServiceName() {
|
||||||
return SERVICE_NAME;
|
return SERVICE_NAME;
|
||||||
|
|
|
@ -15,6 +15,7 @@ package org.openhab.core.config.discovery.addon.mdns.tests;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.ArgumentMatchers.*;
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
import static org.openhab.core.config.discovery.addon.mdns.MDNSAddonFinder.MDNS_SERVICE_TYPE;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -33,6 +34,7 @@ import org.mockito.Mockito;
|
||||||
import org.openhab.core.addon.AddonDiscoveryMethod;
|
import org.openhab.core.addon.AddonDiscoveryMethod;
|
||||||
import org.openhab.core.addon.AddonInfo;
|
import org.openhab.core.addon.AddonInfo;
|
||||||
import org.openhab.core.addon.AddonMatchProperty;
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
import org.openhab.core.config.discovery.addon.AddonFinder;
|
import org.openhab.core.config.discovery.addon.AddonFinder;
|
||||||
import org.openhab.core.config.discovery.addon.AddonFinderConstants;
|
import org.openhab.core.config.discovery.addon.AddonFinderConstants;
|
||||||
import org.openhab.core.config.discovery.addon.AddonSuggestionService;
|
import org.openhab.core.config.discovery.addon.AddonSuggestionService;
|
||||||
|
@ -103,12 +105,12 @@ public class MDNSAddonFinderTests {
|
||||||
AddonDiscoveryMethod hp = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
AddonDiscoveryMethod hp = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
||||||
.setMatchProperties(
|
.setMatchProperties(
|
||||||
List.of(new AddonMatchProperty("rp", ".*"), new AddonMatchProperty("ty", "hp (.*)")))
|
List.of(new AddonMatchProperty("rp", ".*"), new AddonMatchProperty("ty", "hp (.*)")))
|
||||||
.setMdnsServiceType("_printer._tcp.local.");
|
.setParameters(List.of(new AddonParameter(MDNS_SERVICE_TYPE, "_printer._tcp.local.")));
|
||||||
addonInfos.add(AddonInfo.builder("hpprinter", "binding").withName("HP").withDescription("HP Printer")
|
addonInfos.add(AddonInfo.builder("hpprinter", "binding").withName("HP").withDescription("HP Printer")
|
||||||
.withDiscoveryMethods(List.of(hp)).build());
|
.withDiscoveryMethods(List.of(hp)).build());
|
||||||
|
|
||||||
AddonDiscoveryMethod hue = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
AddonDiscoveryMethod hue = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
||||||
.setMdnsServiceType("_hue._tcp.local.");
|
.setParameters(List.of(new AddonParameter(MDNS_SERVICE_TYPE, "_hue._tcp.local.")));
|
||||||
addonInfos.add(AddonInfo.builder("hue", "binding").withName("Hue").withDescription("Hue Bridge")
|
addonInfos.add(AddonInfo.builder("hue", "binding").withName("Hue").withDescription("Hue Bridge")
|
||||||
.withDiscoveryMethods(List.of(hue)).build());
|
.withDiscoveryMethods(List.of(hue)).build());
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.openhab.core.addon.AddonDiscoveryMethod;
|
||||||
import org.openhab.core.addon.AddonInfo;
|
import org.openhab.core.addon.AddonInfo;
|
||||||
import org.openhab.core.addon.AddonInfoProvider;
|
import org.openhab.core.addon.AddonInfoProvider;
|
||||||
import org.openhab.core.addon.AddonMatchProperty;
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
import org.openhab.core.config.discovery.addon.AddonFinder;
|
import org.openhab.core.config.discovery.addon.AddonFinder;
|
||||||
import org.openhab.core.config.discovery.addon.AddonFinderConstants;
|
import org.openhab.core.config.discovery.addon.AddonFinderConstants;
|
||||||
import org.openhab.core.config.discovery.addon.AddonSuggestionService;
|
import org.openhab.core.config.discovery.addon.AddonSuggestionService;
|
||||||
|
@ -52,6 +53,8 @@ import org.osgi.service.cm.ConfigurationAdmin;
|
||||||
@TestInstance(Lifecycle.PER_CLASS)
|
@TestInstance(Lifecycle.PER_CLASS)
|
||||||
public class AddonSuggestionServiceTests {
|
public class AddonSuggestionServiceTests {
|
||||||
|
|
||||||
|
public static final String MDNS_SERVICE_TYPE = "mdnsServiceType";
|
||||||
|
|
||||||
private @NonNullByDefault({}) ConfigurationAdmin configurationAdmin;
|
private @NonNullByDefault({}) ConfigurationAdmin configurationAdmin;
|
||||||
private @NonNullByDefault({}) LocaleProvider localeProvider;
|
private @NonNullByDefault({}) LocaleProvider localeProvider;
|
||||||
private @NonNullByDefault({}) AddonInfoProvider addonInfoProvider;
|
private @NonNullByDefault({}) AddonInfoProvider addonInfoProvider;
|
||||||
|
@ -125,13 +128,13 @@ public class AddonSuggestionServiceTests {
|
||||||
AddonDiscoveryMethod hp = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
AddonDiscoveryMethod hp = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
||||||
.setMatchProperties(
|
.setMatchProperties(
|
||||||
List.of(new AddonMatchProperty("rp", ".*"), new AddonMatchProperty("ty", "hp (.*)")))
|
List.of(new AddonMatchProperty("rp", ".*"), new AddonMatchProperty("ty", "hp (.*)")))
|
||||||
.setMdnsServiceType("_printer._tcp.local.");
|
.setParameters(List.of(new AddonParameter(MDNS_SERVICE_TYPE, "_printer._tcp.local.")));
|
||||||
|
|
||||||
AddonDiscoveryMethod hue1 = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_UPNP)
|
AddonDiscoveryMethod hue1 = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_UPNP)
|
||||||
.setMatchProperties(List.of(new AddonMatchProperty("modelName", "Philips hue bridge")));
|
.setMatchProperties(List.of(new AddonMatchProperty("modelName", "Philips hue bridge")));
|
||||||
|
|
||||||
AddonDiscoveryMethod hue2 = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
AddonDiscoveryMethod hue2 = new AddonDiscoveryMethod().setServiceType(AddonFinderConstants.SERVICE_TYPE_MDNS)
|
||||||
.setMdnsServiceType("_hue._tcp.local.");
|
.setParameters(List.of(new AddonParameter(MDNS_SERVICE_TYPE, "_hue._tcp.local.")));
|
||||||
|
|
||||||
// create the mock
|
// create the mock
|
||||||
addonInfoProvider = mock(AddonInfoProvider.class);
|
addonInfoProvider = mock(AddonInfoProvider.class);
|
||||||
|
|
|
@ -12,12 +12,10 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.core.addon.xml.test;
|
package org.openhab.core.addon.xml.test;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.*;
|
||||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.openhab.core.config.discovery.addon.mdns.MDNSAddonFinder.MDNS_SERVICE_TYPE;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -32,6 +30,7 @@ import org.openhab.core.addon.AddonDiscoveryMethod;
|
||||||
import org.openhab.core.addon.AddonInfo;
|
import org.openhab.core.addon.AddonInfo;
|
||||||
import org.openhab.core.addon.AddonInfoRegistry;
|
import org.openhab.core.addon.AddonInfoRegistry;
|
||||||
import org.openhab.core.addon.AddonMatchProperty;
|
import org.openhab.core.addon.AddonMatchProperty;
|
||||||
|
import org.openhab.core.addon.AddonParameter;
|
||||||
import org.openhab.core.config.core.ConfigDescription;
|
import org.openhab.core.config.core.ConfigDescription;
|
||||||
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
import org.openhab.core.config.core.ConfigDescriptionParameter;
|
||||||
import org.openhab.core.config.core.ConfigDescriptionRegistry;
|
import org.openhab.core.config.core.ConfigDescriptionRegistry;
|
||||||
|
@ -80,7 +79,13 @@ public class AddonInfoTest extends JavaOSGiTest {
|
||||||
AddonDiscoveryMethod discoveryMethod = discoveryMethods.get(0);
|
AddonDiscoveryMethod discoveryMethod = discoveryMethods.get(0);
|
||||||
assertNotNull(discoveryMethod);
|
assertNotNull(discoveryMethod);
|
||||||
assertEquals("mdns", discoveryMethod.getServiceType());
|
assertEquals("mdns", discoveryMethod.getServiceType());
|
||||||
assertEquals("_hue._tcp.local.", discoveryMethod.getMdnsServiceType());
|
List<AddonParameter> parameters = discoveryMethod.getParameters();
|
||||||
|
assertNotNull(parameters);
|
||||||
|
assertEquals(1, parameters.size());
|
||||||
|
AddonParameter parameter = parameters.get(0);
|
||||||
|
assertNotNull(parameter);
|
||||||
|
assertEquals(MDNS_SERVICE_TYPE, parameter.getName());
|
||||||
|
assertEquals("_hue._tcp.local.", parameter.getValue());
|
||||||
List<AddonMatchProperty> properties = discoveryMethod.getMatchProperties();
|
List<AddonMatchProperty> properties = discoveryMethod.getMatchProperties();
|
||||||
assertNotNull(properties);
|
assertNotNull(properties);
|
||||||
assertEquals(0, properties.size());
|
assertEquals(0, properties.size());
|
||||||
|
@ -88,7 +93,9 @@ public class AddonInfoTest extends JavaOSGiTest {
|
||||||
discoveryMethod = discoveryMethods.get(1);
|
discoveryMethod = discoveryMethods.get(1);
|
||||||
assertNotNull(discoveryMethod);
|
assertNotNull(discoveryMethod);
|
||||||
assertEquals("upnp", discoveryMethod.getServiceType());
|
assertEquals("upnp", discoveryMethod.getServiceType());
|
||||||
assertEquals("", discoveryMethod.getMdnsServiceType());
|
parameters = discoveryMethod.getParameters();
|
||||||
|
assertNotNull(parameters);
|
||||||
|
assertEquals(0, parameters.size());
|
||||||
properties = discoveryMethod.getMatchProperties();
|
properties = discoveryMethod.getMatchProperties();
|
||||||
assertNotNull(properties);
|
assertNotNull(properties);
|
||||||
assertEquals(1, properties.size());
|
assertEquals(1, properties.size());
|
||||||
|
|
|
@ -34,7 +34,12 @@
|
||||||
<discovery-methods>
|
<discovery-methods>
|
||||||
<discovery-method>
|
<discovery-method>
|
||||||
<service-type>mdns</service-type>
|
<service-type>mdns</service-type>
|
||||||
<mdns-service-type>_hue._tcp.local.</mdns-service-type>
|
<discovery-parameters>
|
||||||
|
<discovery-parameter>
|
||||||
|
<name>mdnsServiceType</name>
|
||||||
|
<value>_hue._tcp.local.</value>
|
||||||
|
</discovery-parameter>
|
||||||
|
</discovery-parameters>
|
||||||
</discovery-method>
|
</discovery-method>
|
||||||
<discovery-method>
|
<discovery-method>
|
||||||
<service-type>upnp</service-type>
|
<service-type>upnp</service-type>
|
||||||
|
|
Loading…
Reference in New Issue