[openhabcloud] Code improvements (#9131)

* Code improvements
* Add util method to create random alphanimeric string

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
This commit is contained in:
Christoph Weitkamp 2020-11-26 23:14:20 +01:00 committed by GitHub
parent 8c3a488a30
commit aa72044554
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 96 additions and 126 deletions

View File

@ -12,6 +12,8 @@
*/ */
package org.openhab.io.openhabcloud; package org.openhab.io.openhabcloud;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.model.script.engine.action.ActionDoc; import org.openhab.core.model.script.engine.action.ActionDoc;
import org.openhab.io.openhabcloud.internal.CloudService; import org.openhab.io.openhabcloud.internal.CloudService;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -23,14 +25,13 @@ import org.slf4j.LoggerFactory;
* *
* @author Victor Belov - Initial contribution * @author Victor Belov - Initial contribution
* @author Kai Kreuzer - migrated code to ESH APIs * @author Kai Kreuzer - migrated code to ESH APIs
*
*/ */
@NonNullByDefault
public class NotificationAction { public class NotificationAction {
private static final Logger logger = LoggerFactory.getLogger(NotificationAction.class); private static final Logger logger = LoggerFactory.getLogger(NotificationAction.class);
public static CloudService cloudService = null; public static @Nullable CloudService cloudService;
/** /**
* Sends a simple push notification to mobile devices of user * Sends a simple push notification to mobile devices of user
@ -54,7 +55,8 @@ public class NotificationAction {
* *
*/ */
@ActionDoc(text = "Sends a push notification to mobile devices of user with userId") @ActionDoc(text = "Sends a push notification to mobile devices of user with userId")
public static void sendNotification(String userId, String message, String icon, String severity) { public static void sendNotification(String userId, String message, @Nullable String icon,
@Nullable String severity) {
logger.debug("sending notification '{}' to user {}", message, userId); logger.debug("sending notification '{}' to user {}", message, userId);
if (cloudService != null) { if (cloudService != null) {
cloudService.sendNotification(userId, message, icon, severity); cloudService.sendNotification(userId, message, icon, severity);
@ -83,7 +85,7 @@ public class NotificationAction {
* *
*/ */
@ActionDoc(text = "Sends a log notification which is shown in notifications log to all account users") @ActionDoc(text = "Sends a log notification which is shown in notifications log to all account users")
public static void sendLogNotification(String message, String icon, String severity) { public static void sendLogNotification(String message, @Nullable String icon, @Nullable String severity) {
logger.debug("sending log notification '{}'", message); logger.debug("sending log notification '{}'", message);
if (cloudService != null) { if (cloudService != null) {
cloudService.sendLogNotification(message, icon, severity); cloudService.sendLogNotification(message, icon, severity);
@ -112,7 +114,7 @@ public class NotificationAction {
* *
*/ */
@ActionDoc(text = "Sends a push notification to mobile devices of user with userId") @ActionDoc(text = "Sends a push notification to mobile devices of user with userId")
public static void sendBroadcastNotification(String message, String icon, String severity) { public static void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity) {
logger.debug("sending broadcast notification '{}' to all users", message); logger.debug("sending broadcast notification '{}' to all users", message);
if (cloudService != null) { if (cloudService != null) {
cloudService.sendBroadcastNotification(message, icon, severity); cloudService.sendBroadcastNotification(message, icon, severity);

View File

@ -19,14 +19,14 @@ import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Request.FailureListener; import org.eclipse.jetty.client.api.Request.FailureListener;
@ -63,14 +63,12 @@ import io.socket.engineio.client.Transport;
* *
* @author Victor Belov - Initial contribution * @author Victor Belov - Initial contribution
* @author Kai Kreuzer - migrated code to new Jetty client and ESH APIs * @author Kai Kreuzer - migrated code to new Jetty client and ESH APIs
*
*/ */
public class CloudClient { public class CloudClient {
/* /*
* Logger for this class * Logger for this class
*/ */
private Logger logger = LoggerFactory.getLogger(CloudClient.class); private final Logger logger = LoggerFactory.getLogger(CloudClient.class);
/* /*
* This variable holds base URL for the openHAB Cloud connections * This variable holds base URL for the openHAB Cloud connections
@ -98,9 +96,9 @@ public class CloudClient {
private final HttpClient jettyClient; private final HttpClient jettyClient;
/* /*
* This hashmap holds HTTP requests to local openHAB which are currently running * This map holds HTTP requests to local openHAB which are currently running
*/ */
private Map<Integer, Request> runningRequests; private final Map<Integer, Request> runningRequests = new ConcurrentHashMap<>();
/* /*
* This variable indicates if connection to the openHAB Cloud is currently in an established state * This variable indicates if connection to the openHAB Cloud is currently in an established state
@ -147,7 +145,6 @@ public class CloudClient {
this.localBaseUrl = localBaseUrl; this.localBaseUrl = localBaseUrl;
this.remoteAccessEnabled = remoteAccessEnabled; this.remoteAccessEnabled = remoteAccessEnabled;
this.exposedItems = exposedItems; this.exposedItems = exposedItems;
runningRequests = new HashMap<>();
this.jettyClient = httpClient; this.jettyClient = httpClient;
} }
@ -176,11 +173,11 @@ public class CloudClient {
logger.trace("Transport.EVENT_REQUEST_HEADERS"); logger.trace("Transport.EVENT_REQUEST_HEADERS");
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String, List<String>> headers = (Map<String, List<String>>) args[0]; Map<String, List<String>> headers = (Map<String, List<String>>) args[0];
headers.put("uuid", Arrays.asList(uuid)); headers.put("uuid", List.of(uuid));
headers.put("secret", Arrays.asList(secret)); headers.put("secret", List.of(secret));
headers.put("openhabversion", Arrays.asList(OpenHAB.getVersion())); headers.put("openhabversion", List.of(OpenHAB.getVersion()));
headers.put("clientversion", Arrays.asList(CloudService.clientVersion)); headers.put("clientversion", List.of(CloudService.clientVersion));
headers.put("remoteaccess", Arrays.asList(((Boolean) remoteAccessEnabled).toString())); headers.put("remoteaccess", List.of(((Boolean) remoteAccessEnabled).toString()));
} }
}); });
} }
@ -242,10 +239,8 @@ public class CloudClient {
this.localBaseUrl); this.localBaseUrl);
isConnected = false; isConnected = false;
// And clean up the list of running requests // And clean up the list of running requests
if (runningRequests != null) {
runningRequests.clear(); runningRequests.clear();
} }
}
/** /**
* Callback method for socket.io client which is called when an error occurs * Callback method for socket.io client which is called when an error occurs
@ -294,7 +289,6 @@ public class CloudClient {
JSONObject requestQueryJson = data.getJSONObject("query"); JSONObject requestQueryJson = data.getJSONObject("query");
// Create URI builder with base request URI of openHAB and path from request // Create URI builder with base request URI of openHAB and path from request
String newPath = URIUtil.addPaths(localBaseUrl, requestPath); String newPath = URIUtil.addPaths(localBaseUrl, requestPath);
@SuppressWarnings("unchecked")
Iterator<String> queryIterator = requestQueryJson.keys(); Iterator<String> queryIterator = requestQueryJson.keys();
// Add query parameters to URI builder, if any // Add query parameters to URI builder, if any
newPath += "?"; newPath += "?";
@ -345,7 +339,6 @@ public class CloudClient {
} }
private void setRequestHeaders(Request request, JSONObject requestHeadersJson) { private void setRequestHeaders(Request request, JSONObject requestHeadersJson) {
@SuppressWarnings("unchecked")
Iterator<String> headersIterator = requestHeadersJson.keys(); Iterator<String> headersIterator = requestHeadersJson.keys();
// Convert JSONObject of headers into Header ArrayList // Convert JSONObject of headers into Header ArrayList
while (headersIterator.hasNext()) { while (headersIterator.hasNext()) {
@ -368,8 +361,8 @@ public class CloudClient {
int requestId = data.getInt("id"); int requestId = data.getInt("id");
logger.debug("Received cancel for request {}", requestId); logger.debug("Received cancel for request {}", requestId);
// Find and abort running request // Find and abort running request
if (runningRequests.containsKey(requestId)) {
Request request = runningRequests.get(requestId); Request request = runningRequests.get(requestId);
if (request != null) {
request.abort(new InterruptedException()); request.abort(new InterruptedException());
runningRequests.remove(requestId); runningRequests.remove(requestId);
} }
@ -401,9 +394,8 @@ public class CloudClient {
* @param message notification message text * @param message notification message text
* @param icon name of the icon for this notification * @param icon name of the icon for this notification
* @param severity severity name for this notification * @param severity severity name for this notification
*
*/ */
public void sendNotification(String userId, String message, String icon, String severity) { public void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity) {
if (isConnected()) { if (isConnected()) {
JSONObject notificationMessage = new JSONObject(); JSONObject notificationMessage = new JSONObject();
try { try {
@ -426,9 +418,8 @@ public class CloudClient {
* @param message notification message text * @param message notification message text
* @param icon name of the icon for this notification * @param icon name of the icon for this notification
* @param severity severity name for this notification * @param severity severity name for this notification
*
*/ */
public void sendLogNotification(String message, String icon, String severity) { public void sendLogNotification(String message, @Nullable String icon, @Nullable String severity) {
if (isConnected()) { if (isConnected()) {
JSONObject notificationMessage = new JSONObject(); JSONObject notificationMessage = new JSONObject();
try { try {
@ -450,9 +441,8 @@ public class CloudClient {
* @param message notification message text * @param message notification message text
* @param icon name of the icon for this notification * @param icon name of the icon for this notification
* @param severity severity name for this notification * @param severity severity name for this notification
*
*/ */
public void sendBroadcastNotification(String message, String icon, String severity) { public void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity) {
if (isConnected()) { if (isConnected()) {
JSONObject notificationMessage = new JSONObject(); JSONObject notificationMessage = new JSONObject();
try { try {
@ -621,8 +611,6 @@ public class CloudClient {
} catch (JSONException e) { } catch (JSONException e) {
logger.debug("{}", e.getMessage()); logger.debug("{}", e.getMessage());
} }
} else {
// We should not send headers for the second time...
} }
} }
} }

View File

@ -12,6 +12,8 @@
*/ */
package org.openhab.io.openhabcloud.internal; package org.openhab.io.openhabcloud.internal;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* This interface provides callbacks from CloudClient * This interface provides callbacks from CloudClient
* *
@ -19,7 +21,7 @@ package org.openhab.io.openhabcloud.internal;
* @author Kai Kreuzer - migrated code to ESH APIs * @author Kai Kreuzer - migrated code to ESH APIs
* *
*/ */
@NonNullByDefault
public interface CloudClientListener { public interface CloudClientListener {
/** /**
* This method receives command for an item from the openHAB Cloud client and should post it * This method receives command for an item from the openHAB Cloud client and should post it

View File

@ -13,22 +13,18 @@
package org.openhab.io.openhabcloud.internal; package org.openhab.io.openhabcloud.internal;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.nio.charset.StandardCharsets;
import java.io.OutputStream; import java.nio.file.Files;
import java.security.SecureRandom;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.io.IOUtils; import org.eclipse.jdt.annotation.Nullable;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.HttpClient;
import org.openhab.core.OpenHAB; import org.openhab.core.OpenHAB;
import org.openhab.core.config.core.ConfigurableService; import org.openhab.core.config.core.ConfigurableService;
@ -59,8 +55,6 @@ import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate; import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified; import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference; 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;
@ -84,21 +78,33 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
private static final int DEFAULT_LOCAL_OPENHAB_MAX_CONCURRENT_REQUESTS = 200; private static final int DEFAULT_LOCAL_OPENHAB_MAX_CONCURRENT_REQUESTS = 200;
private static final int DEFAULT_LOCAL_OPENHAB_REQUEST_TIMEOUT = 30000; private static final int DEFAULT_LOCAL_OPENHAB_REQUEST_TIMEOUT = 30000;
private static final String HTTPCLIENT_NAME = "openhabcloud"; private static final String HTTPCLIENT_NAME = "openhabcloud";
private static final String CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
private static final SecureRandom SR = new SecureRandom();
private Logger logger = LoggerFactory.getLogger(CloudService.class); private final Logger logger = LoggerFactory.getLogger(CloudService.class);
public static String clientVersion = null; public static String clientVersion = null;
private CloudClient cloudClient; private CloudClient cloudClient;
private String cloudBaseUrl = null; private String cloudBaseUrl = null;
private HttpClient httpClient; private final HttpClient httpClient;
protected ItemRegistry itemRegistry = null; protected final ItemRegistry itemRegistry;
protected EventPublisher eventPublisher = null; protected final EventPublisher eventPublisher;
private boolean remoteAccessEnabled = true; private boolean remoteAccessEnabled = true;
private Set<String> exposedItems = null; private Set<String> exposedItems = null;
private int localPort; private int localPort;
public CloudService() { @Activate
public CloudService(final @Reference HttpClientFactory httpClientFactory,
final @Reference ItemRegistry itemRegistry, final @Reference EventPublisher eventPublisher) {
this.httpClient = httpClientFactory.createHttpClient(HTTPCLIENT_NAME);
this.httpClient.setStopTimeout(0);
this.httpClient.setMaxConnectionsPerDestination(DEFAULT_LOCAL_OPENHAB_MAX_CONCURRENT_REQUESTS);
this.httpClient.setConnectTimeout(DEFAULT_LOCAL_OPENHAB_REQUEST_TIMEOUT);
this.httpClient.setFollowRedirects(false);
this.itemRegistry = itemRegistry;
this.eventPublisher = eventPublisher;
} }
/** /**
@ -109,7 +115,7 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
* @param icon the {@link String} containing a name of the icon to be used with this notification * @param icon the {@link String} containing a name of the icon to be used with this notification
* @param severity the {@link String} containing severity (good, info, warning, error) of notification * @param severity the {@link String} containing severity (good, info, warning, error) of notification
*/ */
public void sendNotification(String userId, String message, String icon, String severity) { public void sendNotification(String userId, String message, @Nullable String icon, @Nullable String severity) {
logger.debug("Sending message '{}' to user id {}", message, userId); logger.debug("Sending message '{}' to user id {}", message, userId);
cloudClient.sendNotification(userId, message, icon, severity); cloudClient.sendNotification(userId, message, icon, severity);
} }
@ -122,7 +128,7 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
* @param icon the {@link String} containing a name of the icon to be used with this notification * @param icon the {@link String} containing a name of the icon to be used with this notification
* @param severity the {@link String} containing severity (good, info, warning, error) of notification * @param severity the {@link String} containing severity (good, info, warning, error) of notification
*/ */
public void sendLogNotification(String message, String icon, String severity) { public void sendLogNotification(String message, @Nullable String icon, @Nullable String severity) {
logger.debug("Sending log message '{}'", message); logger.debug("Sending log message '{}'", message);
cloudClient.sendLogNotification(message, icon, severity); cloudClient.sendLogNotification(message, icon, severity);
} }
@ -135,14 +141,19 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
* @param icon the {@link String} containing a name of the icon to be used with this notification * @param icon the {@link String} containing a name of the icon to be used with this notification
* @param severity the {@link String} containing severity (good, info, warning, error) of notification * @param severity the {@link String} containing severity (good, info, warning, error) of notification
*/ */
public void sendBroadcastNotification(String message, String icon, String severity) { public void sendBroadcastNotification(String message, @Nullable String icon, @Nullable String severity) {
logger.debug("Sending broadcast message '{}' to all users", message); logger.debug("Sending broadcast message '{}' to all users", message);
cloudClient.sendBroadcastNotification(message, icon, severity); cloudClient.sendBroadcastNotification(message, icon, severity);
} }
private String substringBefore(String str, String separator) {
int index = str.indexOf(separator);
return index == -1 ? str : str.substring(0, index);
}
@Activate @Activate
protected void activate(BundleContext context, Map<String, ?> config) { protected void activate(BundleContext context, Map<String, ?> config) {
clientVersion = StringUtils.substringBefore(context.getBundle().getVersion().toString(), ".qualifier"); clientVersion = substringBefore(context.getBundle().getVersion().toString(), ".qualifier");
localPort = HttpServiceUtil.getHttpServicePort(context); localPort = HttpServiceUtil.getHttpServicePort(context);
if (localPort == -1) { if (localPort == -1) {
logger.warn("openHAB Cloud connector not started, since no local HTTP port could be determined"); logger.warn("openHAB Cloud connector not started, since no local HTTP port could be determined");
@ -221,9 +232,6 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
cloudClient.shutdown(); cloudClient.shutdown();
} }
httpClient.setMaxConnectionsPerDestination(DEFAULT_LOCAL_OPENHAB_MAX_CONCURRENT_REQUESTS);
httpClient.setConnectTimeout(DEFAULT_LOCAL_OPENHAB_REQUEST_TIMEOUT);
httpClient.setFollowRedirects(false);
if (!httpClient.isRunning()) { if (!httpClient.isRunning()) {
try { try {
httpClient.start(); httpClient.start();
@ -257,12 +265,12 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
private String readFirstLine(File file) { private String readFirstLine(File file) {
List<String> lines = null; List<String> lines = null;
try (InputStream fis = new FileInputStream(file)) { try {
lines = IOUtils.readLines(fis); lines = Files.readAllLines(file.toPath(), StandardCharsets.UTF_8);
} catch (IOException ioe) { } catch (IOException e) {
// no exception handling - we just return the empty String // no exception handling - we just return the empty String
} }
return lines != null && !lines.isEmpty() ? lines.get(0) : ""; return lines == null || lines.isEmpty() ? "" : lines.get(0);
} }
/** /**
@ -272,8 +280,8 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
private void writeFile(File file, String content) { private void writeFile(File file, String content) {
// create intermediary directories // create intermediary directories
file.getParentFile().mkdirs(); file.getParentFile().mkdirs();
try (OutputStream fos = new FileOutputStream(file)) { try {
IOUtils.write(content, fos); Files.writeString(file.toPath(), content, StandardCharsets.UTF_8);
logger.debug("Created file '{}' with content '{}'", file.getAbsolutePath(), content); logger.debug("Created file '{}' with content '{}'", file.getAbsolutePath(), content);
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
logger.error("Couldn't create file '{}'.", file.getPath(), e); logger.error("Couldn't create file '{}'.", file.getPath(), e);
@ -282,6 +290,14 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
} }
} }
private String randomString(int length) {
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
sb.append(CHARS.charAt(SR.nextInt(CHARS.length())));
}
return sb.toString();
}
/** /**
* Creates a random secret and writes it to the <code>userdata/openhabcloud</code> * Creates a random secret and writes it to the <code>userdata/openhabcloud</code>
* directory. An existing <code>secret</code> file won't be overwritten. * directory. An existing <code>secret</code> file won't be overwritten.
@ -292,7 +308,7 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
String newSecretString = ""; String newSecretString = "";
if (!file.exists()) { if (!file.exists()) {
newSecretString = RandomStringUtils.randomAlphanumeric(20); newSecretString = randomString(20);
logger.debug("New secret = {}", newSecretString); logger.debug("New secret = {}", newSecretString);
writeFile(file, newSecretString); writeFile(file, newSecretString);
} else { } else {
@ -306,11 +322,8 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
@Override @Override
public void sendCommand(String itemName, String commandString) { public void sendCommand(String itemName, String commandString) {
try { try {
if (itemRegistry != null) {
Item item = itemRegistry.getItem(itemName); Item item = itemRegistry.getItem(itemName);
Command command = null; Command command = null;
if (item != null) {
if (this.eventPublisher != null) {
if ("toggle".equalsIgnoreCase(commandString) if ("toggle".equalsIgnoreCase(commandString)
&& (item instanceof SwitchItem || item instanceof RollershutterItem)) { && (item instanceof SwitchItem || item instanceof RollershutterItem)) {
if (OnOffType.ON.equals(item.getStateAs(OnOffType.class))) { if (OnOffType.ON.equals(item.getStateAs(OnOffType.class))) {
@ -330,53 +343,18 @@ public class CloudService implements ActionService, CloudClientListener, EventSu
} }
if (command != null) { if (command != null) {
logger.debug("Received command '{}' for item '{}'", commandString, itemName); logger.debug("Received command '{}' for item '{}'", commandString, itemName);
this.eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, command)); eventPublisher.post(ItemEventFactory.createCommandEvent(itemName, command));
} else { } else {
logger.warn("Received invalid command '{}' for item '{}'", commandString, itemName); logger.warn("Received invalid command '{}' for item '{}'", commandString, itemName);
} }
}
} else {
logger.warn("Received command '{}' for non-existent item '{}'", commandString, itemName);
}
} else {
return;
}
} catch (ItemNotFoundException e) { } catch (ItemNotFoundException e) {
logger.warn("Received command for a non-existent item '{}'", itemName); logger.warn("Received command '{}' for a non-existent item '{}'", commandString, itemName);
} }
} }
@Reference
protected void setHttpClientFactory(HttpClientFactory httpClientFactory) {
this.httpClient = httpClientFactory.createHttpClient(HTTPCLIENT_NAME);
this.httpClient.setStopTimeout(0);
}
protected void unsetHttpClientFactory(HttpClientFactory httpClientFactory) {
this.httpClient = null;
}
@Reference(cardinality = ReferenceCardinality.MANDATORY, policy = ReferencePolicy.DYNAMIC)
public void setItemRegistry(ItemRegistry itemRegistry) {
this.itemRegistry = itemRegistry;
}
public void unsetItemRegistry(ItemRegistry itemRegistry) {
this.itemRegistry = null;
}
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = ReferencePolicy.DYNAMIC)
public void setEventPublisher(EventPublisher eventPublisher) {
this.eventPublisher = eventPublisher;
}
public void unsetEventPublisher(EventPublisher eventPublisher) {
this.eventPublisher = null;
}
@Override @Override
public Set<String> getSubscribedEventTypes() { public Set<String> getSubscribedEventTypes() {
return Collections.singleton(ItemStateEvent.TYPE); return Set.of(ItemStateEvent.TYPE);
} }
@Override @Override