mirror of
https://github.com/danieldemus/openhab-core.git
synced 2025-01-10 21:31:53 +01:00
Fix SAT findings (#2256)
Fixes 65 SAT findings. Signed-off-by: Wouter Born <github@maindrain.net>
This commit is contained in:
parent
ee1d3f3a73
commit
07b95ca668
@ -17,14 +17,19 @@ import java.util.Set;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.openhab.core.automation.module.script.rulesupport.internal.loader.collection.BidiSetBag;
|
import org.openhab.core.automation.module.script.rulesupport.internal.loader.collection.BidiSetBag;
|
||||||
import org.osgi.service.component.annotations.*;
|
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.osgi.service.component.annotations.ReferenceCardinality;
|
||||||
|
import org.osgi.service.component.annotations.ReferencePolicy;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tracks dependencies between scripts and reloads dependees
|
* Tracks dependencies between scripts and reloads dependees
|
||||||
*
|
*
|
||||||
* @author Jonathan Gilbert
|
* @author Jonathan Gilbert - Initial contribution
|
||||||
*/
|
*/
|
||||||
@Component(immediate = true, service = DependencyTracker.class)
|
@Component(immediate = true, service = DependencyTracker.class)
|
||||||
public class DependencyTracker {
|
public class DependencyTracker {
|
||||||
|
@ -16,8 +16,6 @@ import java.net.URISyntaxException;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
@ -36,10 +34,10 @@ import org.slf4j.LoggerFactory;
|
|||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class ScriptFileReference implements Comparable<ScriptFileReference> {
|
public class ScriptFileReference implements Comparable<ScriptFileReference> {
|
||||||
|
|
||||||
private static final Set<String> EXCLUDED_FILE_EXTENSIONS = new HashSet<>(
|
private static final Set<String> EXCLUDED_FILE_EXTENSIONS = Set.of("txt", "old", "example", "backup", "md", "swp",
|
||||||
Arrays.asList("txt", "old", "example", "backup", "md", "swp", "tmp", "bak"));
|
"tmp", "bak");
|
||||||
|
|
||||||
private static final Pattern[] startLevelPatterns = new Pattern[] { Pattern.compile(".*/sl(\\d{2})/[^/]+"), // script
|
private static final Pattern[] START_LEVEL_PATTERNS = new Pattern[] { Pattern.compile(".*/sl(\\d{2})/[^/]+"), // script
|
||||||
// in
|
// in
|
||||||
// immediate
|
// immediate
|
||||||
// slXX
|
// slXX
|
||||||
@ -47,7 +45,7 @@ public class ScriptFileReference implements Comparable<ScriptFileReference> {
|
|||||||
Pattern.compile(".*/[^/]+\\.sl(\\d{2})\\.[^/.]+") // script named <name>.slXX.<ext>
|
Pattern.compile(".*/[^/]+\\.sl(\\d{2})\\.[^/.]+") // script named <name>.slXX.<ext>
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(ScriptFileReference.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ScriptFileReference.class);
|
||||||
|
|
||||||
private final URL scriptFileURL;
|
private final URL scriptFileURL;
|
||||||
|
|
||||||
@ -60,13 +58,13 @@ public class ScriptFileReference implements Comparable<ScriptFileReference> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getStartLevel() {
|
public int getStartLevel() {
|
||||||
for (Pattern p : startLevelPatterns) {
|
for (Pattern p : START_LEVEL_PATTERNS) {
|
||||||
Matcher m = p.matcher(scriptFileURL.getPath());
|
Matcher m = p.matcher(scriptFileURL.getPath());
|
||||||
if (m.find() && m.groupCount() > 0) {
|
if (m.find() && m.groupCount() > 0) {
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt(m.group(1));
|
return Integer.parseInt(m.group(1));
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
logger.warn("Extracted start level {} from {}, but it's not an integer. Ignoring.", m.group(1),
|
LOGGER.warn("Extracted start level {} from {}, but it's not an integer. Ignoring.", m.group(1),
|
||||||
scriptFileURL.getPath());
|
scriptFileURL.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -99,11 +97,11 @@ public class ScriptFileReference implements Comparable<ScriptFileReference> {
|
|||||||
try {
|
try {
|
||||||
Path path1 = Paths.get(scriptFileURL.toURI());
|
Path path1 = Paths.get(scriptFileURL.toURI());
|
||||||
String name1 = path1.getFileName().toString();
|
String name1 = path1.getFileName().toString();
|
||||||
logger.trace("o1 [{}], path1 [{}], name1 [{}]", scriptFileURL, path1, name1);
|
LOGGER.trace("o1 [{}], path1 [{}], name1 [{}]", scriptFileURL, path1, name1);
|
||||||
|
|
||||||
Path path2 = Paths.get(other.scriptFileURL.toURI());
|
Path path2 = Paths.get(other.scriptFileURL.toURI());
|
||||||
String name2 = path2.getFileName().toString();
|
String name2 = path2.getFileName().toString();
|
||||||
logger.trace("o2 [{}], path2 [{}], name2 [{}]", other.scriptFileURL, path2, name2);
|
LOGGER.trace("o2 [{}], path2 [{}], name2 [{}]", other.scriptFileURL, path2, name2);
|
||||||
|
|
||||||
int nameCompare = name1.compareToIgnoreCase(name2);
|
int nameCompare = name1.compareToIgnoreCase(name2);
|
||||||
if (nameCompare != 0) {
|
if (nameCompare != 0) {
|
||||||
@ -112,7 +110,7 @@ public class ScriptFileReference implements Comparable<ScriptFileReference> {
|
|||||||
return path1.getParent().toString().compareToIgnoreCase(path2.getParent().toString());
|
return path1.getParent().toString().compareToIgnoreCase(path2.getParent().toString());
|
||||||
}
|
}
|
||||||
} catch (URISyntaxException e) {
|
} catch (URISyntaxException e) {
|
||||||
logger.error("URI syntax exception", e);
|
LOGGER.error("URI syntax exception", e);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,10 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.WatchEvent;
|
import java.nio.file.WatchEvent;
|
||||||
import java.nio.file.WatchEvent.Kind;
|
import java.nio.file.WatchEvent.Kind;
|
||||||
import java.util.*;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -38,7 +41,11 @@ import org.openhab.core.OpenHAB;
|
|||||||
import org.openhab.core.automation.module.script.ScriptEngineContainer;
|
import org.openhab.core.automation.module.script.ScriptEngineContainer;
|
||||||
import org.openhab.core.automation.module.script.ScriptEngineManager;
|
import org.openhab.core.automation.module.script.ScriptEngineManager;
|
||||||
import org.openhab.core.common.NamedThreadFactory;
|
import org.openhab.core.common.NamedThreadFactory;
|
||||||
import org.openhab.core.service.*;
|
import org.openhab.core.service.AbstractWatchService;
|
||||||
|
import org.openhab.core.service.ReadyMarker;
|
||||||
|
import org.openhab.core.service.ReadyMarkerFilter;
|
||||||
|
import org.openhab.core.service.ReadyService;
|
||||||
|
import org.openhab.core.service.StartLevelService;
|
||||||
import org.osgi.service.component.annotations.Activate;
|
import org.osgi.service.component.annotations.Activate;
|
||||||
import org.osgi.service.component.annotations.Component;
|
import org.osgi.service.component.annotations.Component;
|
||||||
import org.osgi.service.component.annotations.Deactivate;
|
import org.osgi.service.component.annotations.Deactivate;
|
||||||
@ -175,7 +182,6 @@ public class ScriptFileWatcher extends AbstractWatchService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void importFileWhenReady(ScriptFileReference ref) {
|
private synchronized void importFileWhenReady(ScriptFileReference ref) {
|
||||||
|
|
||||||
if (loaded.contains(ref)) {
|
if (loaded.contains(ref)) {
|
||||||
this.removeFile(ref); // if already loaded, remove first
|
this.removeFile(ref); // if already loaded, remove first
|
||||||
}
|
}
|
||||||
@ -192,7 +198,6 @@ public class ScriptFileWatcher extends AbstractWatchService
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void importFile(ScriptFileReference ref) {
|
private void importFile(ScriptFileReference ref) {
|
||||||
|
|
||||||
String fileName = ref.getScriptFileURL().getFile();
|
String fileName = ref.getScriptFileURL().getFile();
|
||||||
Optional<String> scriptType = ref.getScriptType();
|
Optional<String> scriptType = ref.getScriptType();
|
||||||
assert scriptType.isPresent();
|
assert scriptType.isPresent();
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.core.automation.module.script.rulesupport.internal.loader;
|
package org.openhab.core.automation.module.script.rulesupport.internal.loader;
|
||||||
|
|
||||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
|
import static java.nio.file.StandardWatchEventKinds.*;
|
||||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
|
|
||||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -26,7 +24,7 @@ import org.openhab.core.service.AbstractWatchService;
|
|||||||
/**
|
/**
|
||||||
* Listens for changes to script libraries
|
* Listens for changes to script libraries
|
||||||
*
|
*
|
||||||
* @author Jonathan Gilbert
|
* @author Jonathan Gilbert - Initial contribution
|
||||||
*/
|
*/
|
||||||
abstract class ScriptLibraryWatcher extends AbstractWatchService {
|
abstract class ScriptLibraryWatcher extends AbstractWatchService {
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ package org.openhab.core.automation.module.script.rulesupport.internal.loader;
|
|||||||
|
|
||||||
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
|
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
|
||||||
import static org.junit.jupiter.api.Assertions.fail;
|
import static org.junit.jupiter.api.Assertions.fail;
|
||||||
|
import static org.mockito.ArgumentMatchers.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -206,7 +207,6 @@ class ScriptFileWatcherTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoadOneDefaultFileDelayedSupport() {
|
public void testLoadOneDefaultFileDelayedSupport() {
|
||||||
|
|
||||||
// set an executor which captures the scheduled task
|
// set an executor which captures the scheduled task
|
||||||
ScheduledExecutorService scheduledExecutorService = spy(
|
ScheduledExecutorService scheduledExecutorService = spy(
|
||||||
new DelegatingScheduledExecutorService(Executors.newSingleThreadScheduledExecutor()));
|
new DelegatingScheduledExecutorService(Executors.newSingleThreadScheduledExecutor()));
|
||||||
|
@ -12,9 +12,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.openhab.core.automation.module.script.internal;
|
package org.openhab.core.automation.module.script.internal;
|
||||||
|
|
||||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.CONTEXT_KEY_DEPENDENCY_LISTENER;
|
import static org.openhab.core.automation.module.script.ScriptEngineFactory.*;
|
||||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.CONTEXT_KEY_ENGINE_IDENTIFIER;
|
|
||||||
import static org.openhab.core.automation.module.script.ScriptEngineFactory.CONTEXT_KEY_EXTENSION_ACCESSOR;
|
|
||||||
|
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -140,7 +138,6 @@ public class ScriptEngineManagerImpl implements ScriptEngineManager {
|
|||||||
|
|
||||||
addAttributeToScriptContext(engine, CONTEXT_KEY_ENGINE_IDENTIFIER, engineIdentifier);
|
addAttributeToScriptContext(engine, CONTEXT_KEY_ENGINE_IDENTIFIER, engineIdentifier);
|
||||||
addAttributeToScriptContext(engine, CONTEXT_KEY_EXTENSION_ACCESSOR, scriptExtensionManager);
|
addAttributeToScriptContext(engine, CONTEXT_KEY_EXTENSION_ACCESSOR, scriptExtensionManager);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
logger.error("ScriptEngine for language '{}' could not be created for identifier: {}", scriptType,
|
logger.error("ScriptEngine for language '{}' could not be created for identifier: {}", scriptType,
|
||||||
engineIdentifier);
|
engineIdentifier);
|
||||||
|
@ -101,13 +101,11 @@ public class ScriptExtensionManager implements ScriptExtensionAccessor {
|
|||||||
|
|
||||||
public void importDefaultPresets(ScriptEngineFactory engineProvider, ScriptEngine scriptEngine,
|
public void importDefaultPresets(ScriptEngineFactory engineProvider, ScriptEngine scriptEngine,
|
||||||
String scriptIdentifier) {
|
String scriptIdentifier) {
|
||||||
|
|
||||||
engineProvider.scopeValues(scriptEngine, findDefaultPresets(scriptIdentifier));
|
engineProvider.scopeValues(scriptEngine, findDefaultPresets(scriptIdentifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Object> importPreset(String preset, ScriptEngineFactory engineProvider,
|
public Map<String, Object> importPreset(String preset, ScriptEngineFactory engineProvider,
|
||||||
ScriptEngine scriptEngine, String scriptIdentifier) {
|
ScriptEngine scriptEngine, String scriptIdentifier) {
|
||||||
|
|
||||||
Map<String, Object> rv = findPreset(preset, scriptIdentifier);
|
Map<String, Object> rv = findPreset(preset, scriptIdentifier);
|
||||||
|
|
||||||
engineProvider.scopeValues(scriptEngine, rv);
|
engineProvider.scopeValues(scriptEngine, rv);
|
||||||
@ -115,6 +113,7 @@ public class ScriptExtensionManager implements ScriptExtensionAccessor {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, Object> findDefaultPresets(String scriptIdentifier) {
|
public Map<String, Object> findDefaultPresets(String scriptIdentifier) {
|
||||||
Map<String, Object> allValues = new HashMap<>();
|
Map<String, Object> allValues = new HashMap<>();
|
||||||
|
|
||||||
@ -125,6 +124,7 @@ public class ScriptExtensionManager implements ScriptExtensionAccessor {
|
|||||||
return allValues;
|
return allValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Map<String, Object> findPreset(String preset, String scriptIdentifier) {
|
public Map<String, Object> findPreset(String preset, String scriptIdentifier) {
|
||||||
Map<String, Object> allValues = new HashMap<>();
|
Map<String, Object> allValues = new HashMap<>();
|
||||||
for (ScriptExtensionProvider provider : scriptExtensionProviders) {
|
for (ScriptExtensionProvider provider : scriptExtensionProviders) {
|
||||||
|
@ -157,7 +157,7 @@ public class RuleResource implements RESTResource {
|
|||||||
|
|
||||||
Stream<EnrichedRuleDTO> rules = ruleRegistry.stream().filter(p) // filter according to Predicates
|
Stream<EnrichedRuleDTO> rules = ruleRegistry.stream().filter(p) // filter according to Predicates
|
||||||
.map(rule -> EnrichedRuleDTOMapper.map(rule, ruleManager, managedRuleProvider)); // map matching rules
|
.map(rule -> EnrichedRuleDTOMapper.map(rule, ruleManager, managedRuleProvider)); // map matching rules
|
||||||
if (summary != null && summary == true) {
|
if (summary != null && summary) {
|
||||||
rules = dtoMapper.limitToFields(rules, "uid,templateUID,name,visibility,description,status,tags,editable");
|
rules = dtoMapper.limitToFields(rules, "uid,templateUID,name,visibility,description,status,tags,editable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ public class ConfigDescriptionParameterGroupBuilder {
|
|||||||
/**
|
/**
|
||||||
* Sets the advanced flag for this group.
|
* Sets the advanced flag for this group.
|
||||||
*
|
*
|
||||||
* @param advanced - true if the group contains advanced properties
|
* @param advanced true if the group contains advanced properties
|
||||||
* @return the updated builder instance
|
* @return the updated builder instance
|
||||||
*/
|
*/
|
||||||
public ConfigDescriptionParameterGroupBuilder withAdvanced(@Nullable Boolean advanced) {
|
public ConfigDescriptionParameterGroupBuilder withAdvanced(@Nullable Boolean advanced) {
|
||||||
|
@ -16,7 +16,6 @@ import java.util.HashMap;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.events.Event;
|
import org.openhab.core.events.Event;
|
||||||
@ -92,12 +91,12 @@ public class EventLogger implements EventSubscriber, ReadyTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReadyMarkerAdded(@NonNull ReadyMarker readyMarker) {
|
public void onReadyMarkerAdded(ReadyMarker readyMarker) {
|
||||||
loggingActive = true;
|
loggingActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onReadyMarkerRemoved(@NonNull ReadyMarker readyMarker) {
|
public void onReadyMarkerRemoved(ReadyMarker readyMarker) {
|
||||||
loggingActive = false;
|
loggingActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,6 @@ public class ExecUtil {
|
|||||||
*/
|
*/
|
||||||
public static @Nullable String executeCommandLineAndWaitResponse(@Nullable Duration timeout,
|
public static @Nullable String executeCommandLineAndWaitResponse(@Nullable Duration timeout,
|
||||||
String... commandLine) {
|
String... commandLine) {
|
||||||
|
|
||||||
Process processTemp = null;
|
Process processTemp = null;
|
||||||
Future<String> outputFuture = null;
|
Future<String> outputFuture = null;
|
||||||
cleanup: try {
|
cleanup: try {
|
||||||
|
@ -101,7 +101,7 @@ public class WebClientFactoryImplTest {
|
|||||||
|
|
||||||
@Disabled("connecting to the outside world makes this test flaky")
|
@Disabled("connecting to the outside world makes this test flaky")
|
||||||
@Test
|
@Test
|
||||||
public void testCommonClientUsesExtensibleTrustManagerFailure() throws Throwable {
|
public void testCommonClientUsesExtensibleTrustManagerFailure() throws Exception {
|
||||||
doThrow(new CertificateException()).when(extensibleTrustManager).checkServerTrusted(
|
doThrow(new CertificateException()).when(extensibleTrustManager).checkServerTrusted(
|
||||||
ArgumentMatchers.any(X509Certificate[].class), anyString(), ArgumentMatchers.any(SSLEngine.class));
|
ArgumentMatchers.any(X509Certificate[].class), anyString(), ArgumentMatchers.any(SSLEngine.class));
|
||||||
HttpClient httpClient = webClientFactory.getCommonHttpClient();
|
HttpClient httpClient = webClientFactory.getCommonHttpClient();
|
||||||
|
@ -303,7 +303,7 @@ public class ThingResource implements RESTResource {
|
|||||||
|
|
||||||
Stream<EnrichedThingDTO> thingStream = thingRegistry.stream().map(t -> convertToEnrichedThingDTO(t, locale))
|
Stream<EnrichedThingDTO> thingStream = thingRegistry.stream().map(t -> convertToEnrichedThingDTO(t, locale))
|
||||||
.distinct();
|
.distinct();
|
||||||
if (summary != null && summary == true) {
|
if (summary != null && summary) {
|
||||||
thingStream = dtoMapper.limitToFields(thingStream,
|
thingStream = dtoMapper.limitToFields(thingStream,
|
||||||
"UID,label,bridgeUID,thingTypeUID,statusInfo,firmwareStatus,location,editable");
|
"UID,label,bridgeUID,thingTypeUID,statusInfo,firmwareStatus,location,editable");
|
||||||
}
|
}
|
||||||
|
@ -110,7 +110,7 @@ public class UIResource implements RESTResource {
|
|||||||
@QueryParam("summary") @Parameter(description = "summary fields only") @Nullable Boolean summary) {
|
@QueryParam("summary") @Parameter(description = "summary fields only") @Nullable Boolean summary) {
|
||||||
UIComponentRegistry registry = componentRegistryFactory.getRegistry(namespace);
|
UIComponentRegistry registry = componentRegistryFactory.getRegistry(namespace);
|
||||||
Stream<RootUIComponent> components = registry.getAll().stream();
|
Stream<RootUIComponent> components = registry.getAll().stream();
|
||||||
if (summary != null && summary == true) {
|
if (summary != null && summary) {
|
||||||
components = components.map(c -> {
|
components = components.map(c -> {
|
||||||
RootUIComponent component = new RootUIComponent(c.getUID(), c.getType());
|
RootUIComponent component = new RootUIComponent(c.getUID(), c.getType());
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -71,7 +71,6 @@ public class SystemInfoResource implements RESTResource {
|
|||||||
@Operation(operationId = "getSystemInformation", summary = "Gets information about the system.", responses = {
|
@Operation(operationId = "getSystemInformation", summary = "Gets information about the system.", responses = {
|
||||||
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SystemInfoBean.class))) })
|
@ApiResponse(responseCode = "200", description = "OK", content = @Content(schema = @Schema(implementation = SystemInfoBean.class))) })
|
||||||
public Response getSystemInfo(@Context UriInfo uriInfo) {
|
public Response getSystemInfo(@Context UriInfo uriInfo) {
|
||||||
|
|
||||||
final SystemInfoBean bean = new SystemInfoBean();
|
final SystemInfoBean bean = new SystemInfoBean();
|
||||||
return Response.ok(bean).build();
|
return Response.ok(bean).build();
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,6 @@ package org.openhab.core.io.transport.modbus;
|
|||||||
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
|
||||||
@ -115,9 +114,7 @@ public class ModbusConstants {
|
|||||||
* @return ValueType matching the config value
|
* @return ValueType matching the config value
|
||||||
* @throws IllegalArgumentException with unknown value types
|
* @throws IllegalArgumentException with unknown value types
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("null")
|
public static ValueType fromConfigValue(@Nullable String configValueType) throws IllegalArgumentException {
|
||||||
public static @NonNull ValueType fromConfigValue(@Nullable String configValueType)
|
|
||||||
throws IllegalArgumentException {
|
|
||||||
return Stream.of(ValueType.values()).filter(v -> v.getConfigValue().equals(configValueType)).findFirst()
|
return Stream.of(ValueType.values()).filter(v -> v.getConfigValue().equals(configValueType)).findFirst()
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Invalid valueType " + configValueType));
|
.orElseThrow(() -> new IllegalArgumentException("Invalid valueType " + configValueType));
|
||||||
}
|
}
|
||||||
|
@ -961,7 +961,6 @@ public class ModbusManagerImpl implements ModbusManager {
|
|||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
KeyedObjectPool<ModbusSlaveEndpoint, ModbusSlaveConnection> connectionPool = this.connectionPool;
|
KeyedObjectPool<ModbusSlaveEndpoint, ModbusSlaveConnection> connectionPool = this.connectionPool;
|
||||||
if (connectionPool != null) {
|
if (connectionPool != null) {
|
||||||
|
|
||||||
for (ModbusCommunicationInterface commInterface : this.communicationInterfaces) {
|
for (ModbusCommunicationInterface commInterface : this.communicationInterfaces) {
|
||||||
try {
|
try {
|
||||||
commInterface.close();
|
commInterface.close();
|
||||||
|
@ -168,7 +168,6 @@ public class BitUtilitiesCommandToRegistersTest {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public static Stream<Object> data() {
|
public static Stream<Object> data() {
|
||||||
|
|
||||||
return concatTestArgs(//
|
return concatTestArgs(//
|
||||||
|
|
||||||
a("1.0", BIT, IllegalArgumentException.class), a("1.0", INT8, IllegalArgumentException.class),
|
a("1.0", BIT, IllegalArgumentException.class), a("1.0", INT8, IllegalArgumentException.class),
|
||||||
|
@ -60,7 +60,6 @@ public class BitUtilitiesExtractBitTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExtractBitWithRegisterIndexAndBitIndexOOB() {
|
public void testExtractBitWithRegisterIndexAndBitIndexOOB() {
|
||||||
|
|
||||||
byte[] bytes = new byte[] { 0b00100001, // hi byte of 1st register
|
byte[] bytes = new byte[] { 0b00100001, // hi byte of 1st register
|
||||||
0b00100101, // lo byte of 1st register
|
0b00100101, // lo byte of 1st register
|
||||||
0b00110001, // hi byte of 2nd register
|
0b00110001, // hi byte of 2nd register
|
||||||
|
@ -85,14 +85,14 @@ public class IntegrationTestSupport extends JavaTest {
|
|||||||
|
|
||||||
// One can perhaps test SERIAL with https://github.com/freemed/tty0tty
|
// One can perhaps test SERIAL with https://github.com/freemed/tty0tty
|
||||||
// and using those virtual ports? Not the same thing as real serial device of course
|
// and using those virtual ports? Not the same thing as real serial device of course
|
||||||
private static String SERIAL_SERVER_PORT = "/dev/pts/7";
|
private static final String SERIAL_SERVER_PORT = "/dev/pts/7";
|
||||||
private static String SERIAL_CLIENT_PORT = "/dev/pts/8";
|
private static final String SERIAL_CLIENT_PORT = "/dev/pts/8";
|
||||||
|
|
||||||
private static SerialParameters SERIAL_PARAMETERS_CLIENT = new SerialParameters(SERIAL_CLIENT_PORT, 115200,
|
private static final SerialParameters SERIAL_PARAMETERS_CLIENT = new SerialParameters(SERIAL_CLIENT_PORT, 115200,
|
||||||
SerialPort.FLOWCONTROL_NONE, SerialPort.FLOWCONTROL_NONE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
|
SerialPort.FLOWCONTROL_NONE, SerialPort.FLOWCONTROL_NONE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1,
|
||||||
SerialPort.PARITY_NONE, Modbus.SERIAL_ENCODING_ASCII, false, 1000);
|
SerialPort.PARITY_NONE, Modbus.SERIAL_ENCODING_ASCII, false, 1000);
|
||||||
|
|
||||||
private static SerialParameters SERIAL_PARAMETERS_SERVER = new SerialParameters(SERIAL_SERVER_PORT,
|
private static final SerialParameters SERIAL_PARAMETERS_SERVER = new SerialParameters(SERIAL_SERVER_PORT,
|
||||||
SERIAL_PARAMETERS_CLIENT.getBaudRate(), SERIAL_PARAMETERS_CLIENT.getFlowControlIn(),
|
SERIAL_PARAMETERS_CLIENT.getBaudRate(), SERIAL_PARAMETERS_CLIENT.getFlowControlIn(),
|
||||||
SERIAL_PARAMETERS_CLIENT.getFlowControlOut(), SERIAL_PARAMETERS_CLIENT.getDatabits(),
|
SERIAL_PARAMETERS_CLIENT.getFlowControlOut(), SERIAL_PARAMETERS_CLIENT.getDatabits(),
|
||||||
SERIAL_PARAMETERS_CLIENT.getStopbits(), SERIAL_PARAMETERS_CLIENT.getParity(),
|
SERIAL_PARAMETERS_CLIENT.getStopbits(), SERIAL_PARAMETERS_CLIENT.getParity(),
|
||||||
@ -106,14 +106,14 @@ public class IntegrationTestSupport extends JavaTest {
|
|||||||
/**
|
/**
|
||||||
* Max time to wait for connections/requests from client
|
* Max time to wait for connections/requests from client
|
||||||
*/
|
*/
|
||||||
protected int MAX_WAIT_REQUESTS_MILLIS = 1000;
|
protected static final int MAX_WAIT_REQUESTS_MILLIS = 1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The server runs in single thread, only one connection is accepted at a time.
|
* The server runs in single thread, only one connection is accepted at a time.
|
||||||
* This makes the tests as strict as possible -- connection must be closed.
|
* This makes the tests as strict as possible -- connection must be closed.
|
||||||
*/
|
*/
|
||||||
private static final int SERVER_THREADS = 1;
|
private static final int SERVER_THREADS = 1;
|
||||||
protected static int SLAVE_UNIT_ID = 1;
|
protected static final int SLAVE_UNIT_ID = 1;
|
||||||
|
|
||||||
private static AtomicCounter udpServerIndex = new AtomicCounter(0);
|
private static AtomicCounter udpServerIndex = new AtomicCounter(0);
|
||||||
|
|
||||||
|
@ -73,10 +73,10 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
private static final int DISCRETE_EVERY_N_TRUE = 3;
|
private static final int DISCRETE_EVERY_N_TRUE = 3;
|
||||||
private static final int HOLDING_REGISTER_MULTIPLIER = 1;
|
private static final int HOLDING_REGISTER_MULTIPLIER = 1;
|
||||||
private static final int INPUT_REGISTER_MULTIPLIER = 10;
|
private static final int INPUT_REGISTER_MULTIPLIER = 10;
|
||||||
private static final SpyingSocketFactory socketSpy = new SpyingSocketFactory();
|
private static final SpyingSocketFactory SOCKET_SPY = new SpyingSocketFactory();
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
Socket.setSocketImplFactory(socketSpy);
|
Socket.setSocketImplFactory(SOCKET_SPY);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
fail("Could not install socket spy in SmokeTest");
|
fail("Could not install socket spy in SmokeTest");
|
||||||
}
|
}
|
||||||
@ -138,7 +138,7 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUpSocketSpy() throws IOException {
|
public void setUpSocketSpy() throws IOException {
|
||||||
socketSpy.sockets.clear();
|
SOCKET_SPY.sockets.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -844,7 +844,7 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
config.setReconnectAfterMillis(9_000_000);
|
config.setReconnectAfterMillis(9_000_000);
|
||||||
|
|
||||||
// 1. capture open connections at this point
|
// 1. capture open connections at this point
|
||||||
long openSocketsBefore = getNumberOfOpenClients(socketSpy);
|
long openSocketsBefore = getNumberOfOpenClients(SOCKET_SPY);
|
||||||
assertThat(openSocketsBefore, is(equalTo(0L)));
|
assertThat(openSocketsBefore, is(equalTo(0L)));
|
||||||
|
|
||||||
// 2. make poll, binding opens the tcp connection
|
// 2. make poll, binding opens the tcp connection
|
||||||
@ -861,7 +861,7 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
}
|
}
|
||||||
waitForAssert(() -> {
|
waitForAssert(() -> {
|
||||||
// 3. ensure one open connection
|
// 3. ensure one open connection
|
||||||
long openSocketsAfter = getNumberOfOpenClients(socketSpy);
|
long openSocketsAfter = getNumberOfOpenClients(SOCKET_SPY);
|
||||||
assertThat(openSocketsAfter, is(equalTo(1L)));
|
assertThat(openSocketsAfter, is(equalTo(1L)));
|
||||||
});
|
});
|
||||||
try (ModbusCommunicationInterface comms2 = modbusManager.newModbusCommunicationInterface(endpoint,
|
try (ModbusCommunicationInterface comms2 = modbusManager.newModbusCommunicationInterface(endpoint,
|
||||||
@ -876,21 +876,21 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
});
|
});
|
||||||
assertTrue(latch.await(60, TimeUnit.SECONDS));
|
assertTrue(latch.await(60, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
assertThat(getNumberOfOpenClients(socketSpy), is(equalTo(1L)));
|
assertThat(getNumberOfOpenClients(SOCKET_SPY), is(equalTo(1L)));
|
||||||
// wait for moment (to check that no connections are closed)
|
// wait for moment (to check that no connections are closed)
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
// no more than 1 connection, even though requests are going through
|
// no more than 1 connection, even though requests are going through
|
||||||
assertThat(getNumberOfOpenClients(socketSpy), is(equalTo(1L)));
|
assertThat(getNumberOfOpenClients(SOCKET_SPY), is(equalTo(1L)));
|
||||||
}
|
}
|
||||||
Thread.sleep(1000);
|
Thread.sleep(1000);
|
||||||
// Still one connection open even after closing second connection
|
// Still one connection open even after closing second connection
|
||||||
assertThat(getNumberOfOpenClients(socketSpy), is(equalTo(1L)));
|
assertThat(getNumberOfOpenClients(SOCKET_SPY), is(equalTo(1L)));
|
||||||
|
|
||||||
} // 4. close (the last) comms
|
} // 4. close (the last) comms
|
||||||
// ensure that open connections are closed
|
// ensure that open connections are closed
|
||||||
// (despite huge "reconnect after millis")
|
// (despite huge "reconnect after millis")
|
||||||
waitForAssert(() -> {
|
waitForAssert(() -> {
|
||||||
long openSocketsAfterClose = getNumberOfOpenClients(socketSpy);
|
long openSocketsAfterClose = getNumberOfOpenClients(SOCKET_SPY);
|
||||||
assertThat(openSocketsAfterClose, is(equalTo(0L)));
|
assertThat(openSocketsAfterClose, is(equalTo(0L)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -909,7 +909,7 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
config.setReconnectAfterMillis(2_000);
|
config.setReconnectAfterMillis(2_000);
|
||||||
|
|
||||||
// 1. capture open connections at this point
|
// 1. capture open connections at this point
|
||||||
long openSocketsBefore = getNumberOfOpenClients(socketSpy);
|
long openSocketsBefore = getNumberOfOpenClients(SOCKET_SPY);
|
||||||
assertThat(openSocketsBefore, is(equalTo(0L)));
|
assertThat(openSocketsBefore, is(equalTo(0L)));
|
||||||
|
|
||||||
// 2. make poll, binding opens the tcp connection
|
// 2. make poll, binding opens the tcp connection
|
||||||
@ -927,14 +927,14 @@ public class SmokeTest extends IntegrationTestSupport {
|
|||||||
// Right after the poll we should have one connection open
|
// Right after the poll we should have one connection open
|
||||||
waitForAssert(() -> {
|
waitForAssert(() -> {
|
||||||
// 3. ensure one open connection
|
// 3. ensure one open connection
|
||||||
long openSocketsAfter = getNumberOfOpenClients(socketSpy);
|
long openSocketsAfter = getNumberOfOpenClients(SOCKET_SPY);
|
||||||
assertThat(openSocketsAfter, is(equalTo(1L)));
|
assertThat(openSocketsAfter, is(equalTo(1L)));
|
||||||
});
|
});
|
||||||
// 4. Connection should close itself by the commons pool eviction policy (checking for old idle connection
|
// 4. Connection should close itself by the commons pool eviction policy (checking for old idle connection
|
||||||
// every now and then)
|
// every now and then)
|
||||||
waitForAssert(() -> {
|
waitForAssert(() -> {
|
||||||
// 3. ensure one open connection
|
// 3. ensure one open connection
|
||||||
long openSocketsAfter = getNumberOfOpenClients(socketSpy);
|
long openSocketsAfter = getNumberOfOpenClients(SOCKET_SPY);
|
||||||
assertThat(openSocketsAfter, is(equalTo(0L)));
|
assertThat(openSocketsAfter, is(equalTo(0L)));
|
||||||
}, 60_000, 50);
|
}, 60_000, 50);
|
||||||
|
|
||||||
|
@ -35,14 +35,14 @@ import org.openhab.core.io.transport.modbus.json.WriteRequestJsonUtilities;
|
|||||||
*/
|
*/
|
||||||
public class WriteRequestJsonUtilitiesTest {
|
public class WriteRequestJsonUtilitiesTest {
|
||||||
|
|
||||||
private static List<String> MAX_REGISTERS = IntStream.range(0, MAX_REGISTERS_WRITE_COUNT).mapToObj(i -> "1")
|
private static final List<String> MAX_REGISTERS = IntStream.range(0, MAX_REGISTERS_WRITE_COUNT).mapToObj(i -> "1")
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
private static List<String> OVER_MAX_REGISTERS = IntStream.range(0, MAX_REGISTERS_WRITE_COUNT + 1)
|
private static final List<String> OVER_MAX_REGISTERS = IntStream.range(0, MAX_REGISTERS_WRITE_COUNT + 1)
|
||||||
.mapToObj(i -> "1").collect(Collectors.toList());
|
.mapToObj(i -> "1").collect(Collectors.toList());
|
||||||
|
|
||||||
private static List<String> MAX_COILS = IntStream.range(0, MAX_BITS_WRITE_COUNT).mapToObj(i -> "1")
|
private static final List<String> MAX_COILS = IntStream.range(0, MAX_BITS_WRITE_COUNT).mapToObj(i -> "1")
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
private static List<String> OVER_MAX_COILS = IntStream.range(0, MAX_BITS_WRITE_COUNT + 1).mapToObj(i -> "1")
|
private static final List<String> OVER_MAX_COILS = IntStream.range(0, MAX_BITS_WRITE_COUNT + 1).mapToObj(i -> "1")
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -29,20 +29,20 @@ public class MagicServiceConfig {
|
|||||||
public BigDecimal decimal;
|
public BigDecimal decimal;
|
||||||
public Integer integer;
|
public Integer integer;
|
||||||
|
|
||||||
public String text_advanced;
|
public String textAdvanced;
|
||||||
public boolean boolean_advanced;
|
public boolean booleanAdvanced;
|
||||||
public BigDecimal decimal_advanced;
|
public BigDecimal decimalAdvanced;
|
||||||
public Integer integer_advanced;
|
public Integer integerAdvanced;
|
||||||
|
|
||||||
public String requiredTextParameter;
|
public String requiredTextParameter;
|
||||||
public String verifiedTextParameter;
|
public String verifiedTextParameter;
|
||||||
public String select_limited;
|
public String selectLimited;
|
||||||
public String select_variable;
|
public String selectVariable;
|
||||||
|
|
||||||
public List<String> multiselect_text_limit;
|
public List<String> multiselectTextLimit;
|
||||||
public List<BigDecimal> multiselect_integer_limit;
|
public List<BigDecimal> multiselectIntegerLimit;
|
||||||
|
|
||||||
public BigDecimal select_decimal_limit;
|
public BigDecimal selectDecimalLimit;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -38,22 +38,22 @@
|
|||||||
<default>42</default>
|
<default>42</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
|
|
||||||
<parameter name="text_advanced" type="text" groupName="group_advanced">
|
<parameter name="textAdvanced" type="text" groupName="group_advanced">
|
||||||
<label>Text</label>
|
<label>Text</label>
|
||||||
<description>A grouped text parameter.</description>
|
<description>A grouped text parameter.</description>
|
||||||
<default>myText</default>
|
<default>myText</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="boolean_advanced" type="boolean" groupName="group_advanced">
|
<parameter name="booleanAdvanced" type="boolean" groupName="group_advanced">
|
||||||
<label>Switch</label>
|
<label>Switch</label>
|
||||||
<description>A grouped boolean parameter.</description>
|
<description>A grouped boolean parameter.</description>
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="decimal_advanced" type="decimal" groupName="group_advanced">
|
<parameter name="decimalAdvanced" type="decimal" groupName="group_advanced">
|
||||||
<label>Decimal</label>
|
<label>Decimal</label>
|
||||||
<description>A grouped decimal parameter.</description>
|
<description>A grouped decimal parameter.</description>
|
||||||
<default>3.141592</default>
|
<default>3.141592</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="integer_advanced" type="integer" groupName="group_advanced">
|
<parameter name="integerAdvanced" type="integer" groupName="group_advanced">
|
||||||
<label>Integer</label>
|
<label>Integer</label>
|
||||||
<description>A grouped integer parameter.</description>
|
<description>A grouped integer parameter.</description>
|
||||||
<default>42</default>
|
<default>42</default>
|
||||||
@ -68,7 +68,7 @@
|
|||||||
<description>A text parameter which is required and must be verified by the user.</description>
|
<description>A text parameter which is required and must be verified by the user.</description>
|
||||||
<verify>true</verify>
|
<verify>true</verify>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="select_limited" type="text" required="false">
|
<parameter name="selectLimited" type="text" required="false">
|
||||||
<label>Select limited</label>
|
<label>Select limited</label>
|
||||||
<description>A select text parameter which is restricted to the given options.</description>
|
<description>A select text parameter which is restricted to the given options.</description>
|
||||||
<options>
|
<options>
|
||||||
@ -79,7 +79,7 @@
|
|||||||
<limitToOptions>true</limitToOptions>
|
<limitToOptions>true</limitToOptions>
|
||||||
<default>value1</default>
|
<default>value1</default>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="select_variable" type="text" required="false">
|
<parameter name="selectVariable" type="text" required="false">
|
||||||
<label>Select variable</label>
|
<label>Select variable</label>
|
||||||
<description>A select text parameter without limit.</description>
|
<description>A select text parameter without limit.</description>
|
||||||
<options>
|
<options>
|
||||||
@ -89,7 +89,7 @@
|
|||||||
</options>
|
</options>
|
||||||
<limitToOptions>false</limitToOptions>
|
<limitToOptions>false</limitToOptions>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="multiselect_integer_limit" type="integer" multiple="true">
|
<parameter name="multiselectIntegerLimit" type="integer" multiple="true">
|
||||||
<label>Multiselect Integer - limit</label>
|
<label>Multiselect Integer - limit</label>
|
||||||
<description>An integer parameter limited to </description>
|
<description>An integer parameter limited to </description>
|
||||||
<multipleLimit>3</multipleLimit>
|
<multipleLimit>3</multipleLimit>
|
||||||
@ -107,7 +107,7 @@
|
|||||||
<option value="0">Zero</option>
|
<option value="0">Zero</option>
|
||||||
</options>
|
</options>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="multiselect_text_limit" type="text" multiple="true">
|
<parameter name="multiselectTextLimit" type="text" multiple="true">
|
||||||
<label>Multiselect Text - limit</label>
|
<label>Multiselect Text - limit</label>
|
||||||
<description>An integer parameter limited to </description>
|
<description>An integer parameter limited to </description>
|
||||||
<multipleLimit>3</multipleLimit>
|
<multipleLimit>3</multipleLimit>
|
||||||
@ -125,7 +125,7 @@
|
|||||||
<option value="value0">Zero</option>
|
<option value="value0">Zero</option>
|
||||||
</options>
|
</options>
|
||||||
</parameter>
|
</parameter>
|
||||||
<parameter name="select_decimal_limit" type="decimal">
|
<parameter name="selectDecimalLimit" type="decimal">
|
||||||
<label>Select Decimal - options from backend</label>
|
<label>Select Decimal - options from backend</label>
|
||||||
<description>A decimal parameter with options provided by the backend.</description>
|
<description>A decimal parameter with options provided by the backend.</description>
|
||||||
<limitToOptions>true</limitToOptions>
|
<limitToOptions>true</limitToOptions>
|
||||||
|
@ -137,8 +137,9 @@ public class ThingFactoryHelper {
|
|||||||
final ChannelUID channelUID = new ChannelUID(thingUID, groupId, channelDefinition.getId());
|
final ChannelUID channelUID = new ChannelUID(thingUID, groupId, channelDefinition.getId());
|
||||||
final ChannelBuilder channelBuilder = createChannelBuilder(channelUID, channelDefinition,
|
final ChannelBuilder channelBuilder = createChannelBuilder(channelUID, channelDefinition,
|
||||||
configDescriptionRegistry);
|
configDescriptionRegistry);
|
||||||
if (channelBuilder == null)
|
if (channelBuilder == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return channelBuilder.withProperties(channelDefinition.getProperties()).build();
|
return channelBuilder.withProperties(channelDefinition.getProperties()).build();
|
||||||
}
|
}
|
||||||
@ -169,7 +170,6 @@ public class ThingFactoryHelper {
|
|||||||
|
|
||||||
static ChannelBuilder createChannelBuilder(ChannelUID channelUID, ChannelDefinition channelDefinition,
|
static ChannelBuilder createChannelBuilder(ChannelUID channelUID, ChannelDefinition channelDefinition,
|
||||||
ConfigDescriptionRegistry configDescriptionRegistry) {
|
ConfigDescriptionRegistry configDescriptionRegistry) {
|
||||||
|
|
||||||
ChannelType channelType = withChannelTypeRegistry(channelTypeRegistry -> {
|
ChannelType channelType = withChannelTypeRegistry(channelTypeRegistry -> {
|
||||||
return (channelTypeRegistry != null)
|
return (channelTypeRegistry != null)
|
||||||
? channelTypeRegistry.getChannelType(channelDefinition.getChannelTypeUID())
|
? channelTypeRegistry.getChannelType(channelDefinition.getChannelTypeUID())
|
||||||
@ -182,8 +182,9 @@ public class ThingFactoryHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String label = channelDefinition.getLabel();
|
String label = channelDefinition.getLabel();
|
||||||
if (label == null)
|
if (label == null) {
|
||||||
label = channelType.getLabel();
|
label = channelType.getLabel();
|
||||||
|
}
|
||||||
|
|
||||||
final ChannelBuilder channelBuilder = ChannelBuilder.create(channelUID, channelType.getItemType()) //
|
final ChannelBuilder channelBuilder = ChannelBuilder.create(channelUID, channelType.getItemType()) //
|
||||||
.withType(channelType.getUID()) //
|
.withType(channelType.getUID()) //
|
||||||
|
@ -16,8 +16,6 @@ import java.io.Serializable;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the Access Token Response, a simple value-object that holds the result of the
|
* This is the Access Token Response, a simple value-object that holds the result of the
|
||||||
* from an Access Token Request, as listed in RFC 6749:
|
* from an Access Token Request, as listed in RFC 6749:
|
||||||
@ -112,7 +110,7 @@ public final class AccessTokenResponse implements Serializable, Cloneable {
|
|||||||
* by the authorization server.
|
* by the authorization server.
|
||||||
* @return true if object is not-initialized, or expired, or expired early due to buffer
|
* @return true if object is not-initialized, or expired, or expired early due to buffer
|
||||||
*/
|
*/
|
||||||
public boolean isExpired(@NonNull LocalDateTime givenTime, int tokenExpiresInBuffer) {
|
public boolean isExpired(LocalDateTime givenTime, int tokenExpiresInBuffer) {
|
||||||
return createdOn == null
|
return createdOn == null
|
||||||
|| createdOn.plusSeconds(expiresIn).minusSeconds(tokenExpiresInBuffer).isBefore(givenTime);
|
|| createdOn.plusSeconds(expiresIn).minusSeconds(tokenExpiresInBuffer).isBefore(givenTime);
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ public class ExpireManager implements EventSubscriber, RegistryChangeListener<It
|
|||||||
protected static final String COMMAND_PREFIX = "command=";
|
protected static final String COMMAND_PREFIX = "command=";
|
||||||
protected static final String STATE_PREFIX = "state=";
|
protected static final String STATE_PREFIX = "state=";
|
||||||
|
|
||||||
protected static final Pattern durationPattern = Pattern
|
protected static final Pattern DURATION_PATTERN = Pattern
|
||||||
.compile("(?:([0-9]+)H)?\\s*(?:([0-9]+)M)?\\s*(?:([0-9]+)S)?", Pattern.CASE_INSENSITIVE);
|
.compile("(?:([0-9]+)H)?\\s*(?:([0-9]+)M)?\\s*(?:([0-9]+)S)?", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -362,7 +362,7 @@ public class ExpireManager implements EventSubscriber, RegistryChangeListener<It
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Duration parseDuration(String durationString) throws IllegalArgumentException {
|
private Duration parseDuration(String durationString) throws IllegalArgumentException {
|
||||||
Matcher m = durationPattern.matcher(durationString);
|
Matcher m = DURATION_PATTERN.matcher(durationString);
|
||||||
if (!m.matches() || (m.group(1) == null && m.group(2) == null && m.group(3) == null)) {
|
if (!m.matches() || (m.group(1) == null && m.group(2) == null && m.group(3) == null)) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Invalid duration: " + durationString + ". Expected something like: '1h 15m 30s'");
|
"Invalid duration: " + durationString + ". Expected something like: '1h 15m 30s'");
|
||||||
|
@ -72,7 +72,7 @@ public class QuantityType<T extends Quantity<T>> extends Number
|
|||||||
UnitInitializer.init();
|
UnitInitializer.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private transient final Logger logger = LoggerFactory.getLogger(QuantityType.class);
|
private final transient Logger logger = LoggerFactory.getLogger(QuantityType.class);
|
||||||
|
|
||||||
private final Quantity<T> quantity;
|
private final Quantity<T> quantity;
|
||||||
|
|
||||||
|
@ -26,7 +26,6 @@ import java.util.concurrent.ScheduledFuture;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.openhab.core.common.NamedThreadFactory;
|
import org.openhab.core.common.NamedThreadFactory;
|
||||||
@ -72,16 +71,16 @@ import org.slf4j.LoggerFactory;
|
|||||||
@Component(immediate = true, configurationPid = "org.openhab.startlevel", configurationPolicy = ConfigurationPolicy.REQUIRE)
|
@Component(immediate = true, configurationPid = "org.openhab.startlevel", configurationPolicy = ConfigurationPolicy.REQUIRE)
|
||||||
public class StartLevelService {
|
public class StartLevelService {
|
||||||
|
|
||||||
public final static String STARTLEVEL_MARKER_TYPE = "startlevel";
|
public static final String STARTLEVEL_MARKER_TYPE = "startlevel";
|
||||||
|
|
||||||
public final static int STARTLEVEL_OSGI = 10;
|
public static final int STARTLEVEL_OSGI = 10;
|
||||||
public final static int STARTLEVEL_MODEL = 20;
|
public static final int STARTLEVEL_MODEL = 20;
|
||||||
public final static int STARTLEVEL_STATES = 30;
|
public static final int STARTLEVEL_STATES = 30;
|
||||||
public final static int STARTLEVEL_RULES = 40;
|
public static final int STARTLEVEL_RULES = 40;
|
||||||
public final static int STARTLEVEL_RULEENGINE = 50;
|
public static final int STARTLEVEL_RULEENGINE = 50;
|
||||||
public final static int STARTLEVEL_UI = 70;
|
public static final int STARTLEVEL_UI = 70;
|
||||||
public final static int STARTLEVEL_THINGS = 80;
|
public static final int STARTLEVEL_THINGS = 80;
|
||||||
public final static int STARTLEVEL_COMPLETE = 100;
|
public static final int STARTLEVEL_COMPLETE = 100;
|
||||||
|
|
||||||
private final Logger logger = LoggerFactory.getLogger(StartLevelService.class);
|
private final Logger logger = LoggerFactory.getLogger(StartLevelService.class);
|
||||||
|
|
||||||
@ -91,7 +90,7 @@ public class StartLevelService {
|
|||||||
|
|
||||||
private final Set<ReadyMarker> markers = ConcurrentHashMap.newKeySet();
|
private final Set<ReadyMarker> markers = ConcurrentHashMap.newKeySet();
|
||||||
private final Map<String, ReadyTracker> trackers = new ConcurrentHashMap<>();
|
private final Map<String, ReadyTracker> trackers = new ConcurrentHashMap<>();
|
||||||
private final Map<Integer, @NonNull ReadyMarker> slmarker = new ConcurrentHashMap<>();
|
private final Map<Integer, ReadyMarker> slmarker = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
private @Nullable ScheduledFuture<?> job;
|
private @Nullable ScheduledFuture<?> job;
|
||||||
private final ScheduledExecutorService scheduler = Executors
|
private final ScheduledExecutorService scheduler = Executors
|
||||||
|
@ -81,7 +81,7 @@ public class SchedulerImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
||||||
public void testAfterResolvedWithException() throws Throwable {
|
public void testAfterResolvedWithException() throws InterruptedException {
|
||||||
Callable<Void> callable = () -> {
|
Callable<Void> callable = () -> {
|
||||||
// Pass a exception not very likely thrown by the scheduler it self to avoid missing real exceptions.
|
// Pass a exception not very likely thrown by the scheduler it self to avoid missing real exceptions.
|
||||||
throw new FileNotFoundException("testBeforeTimeoutException");
|
throw new FileNotFoundException("testBeforeTimeoutException");
|
||||||
@ -103,7 +103,7 @@ public class SchedulerImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
||||||
public void testBeforeTimeoutException() throws Throwable {
|
public void testBeforeTimeoutException() throws InterruptedException, ExecutionException {
|
||||||
CompletableFuture<Integer> d = new CompletableFuture<>();
|
CompletableFuture<Integer> d = new CompletableFuture<>();
|
||||||
ScheduledCompletableFuture<Integer> before = scheduler.before(d, Duration.ofMillis(100));
|
ScheduledCompletableFuture<Integer> before = scheduler.before(d, Duration.ofMillis(100));
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
@ -145,7 +145,7 @@ public class SchedulerImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
||||||
public void testBeforeResolvedWithException() throws Throwable {
|
public void testBeforeResolvedWithException() throws InterruptedException {
|
||||||
CompletableFuture<Integer> d = new CompletableFuture<>();
|
CompletableFuture<Integer> d = new CompletableFuture<>();
|
||||||
ScheduledCompletableFuture<Integer> before = scheduler.before(d, Duration.ofMillis(100));
|
ScheduledCompletableFuture<Integer> before = scheduler.before(d, Duration.ofMillis(100));
|
||||||
// Pass an exception not very likely thrown by the scheduler it self to avoid missing real exceptions.
|
// Pass an exception not very likely thrown by the scheduler it self to avoid missing real exceptions.
|
||||||
@ -164,7 +164,7 @@ public class SchedulerImplTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
@Timeout(value = 300, unit = TimeUnit.MILLISECONDS)
|
||||||
public void testAfterTimeoutException() throws Throwable {
|
public void testAfterTimeoutException() throws InterruptedException, ExecutionException {
|
||||||
CompletableFuture<Integer> d = new CompletableFuture<>();
|
CompletableFuture<Integer> d = new CompletableFuture<>();
|
||||||
ScheduledCompletableFuture<Integer> before = scheduler.before(d, Duration.ofMillis(100));
|
ScheduledCompletableFuture<Integer> before = scheduler.before(d, Duration.ofMillis(100));
|
||||||
Thread.sleep(200);
|
Thread.sleep(200);
|
||||||
|
@ -32,9 +32,9 @@ public class UIDUtilsTest {
|
|||||||
Consumer<String> test = in -> {
|
Consumer<String> test = in -> {
|
||||||
final String encoded = UIDUtils.encode(in);
|
final String encoded = UIDUtils.encode(in);
|
||||||
final String decoded = UIDUtils.decode(encoded);
|
final String decoded = UIDUtils.decode(encoded);
|
||||||
System.out.printf("in: %s%n encoded: %s%n decoded: %s%n equals: %b%n", in, encoded, decoded,
|
final String reason = String.format("in: %s%n encoded: %s%n decoded: %s%n equals: %b%n", in, encoded,
|
||||||
in.equals(decoded));
|
decoded, in.equals(decoded));
|
||||||
assertThat(decoded, IsEqual.equalTo(in));
|
assertThat(reason, decoded, IsEqual.equalTo(in));
|
||||||
};
|
};
|
||||||
test.accept("test");
|
test.accept("test");
|
||||||
test.accept("TEST");
|
test.accept("TEST");
|
||||||
|
Loading…
Reference in New Issue
Block a user