[neeo] fix ClassNotFoundException and switch to constructor injection (#9006)
Signed-off-by: Jan N. Klug <jan.n.klug@rub.de>
This commit is contained in:
parent
02341d3536
commit
1073f0086d
|
@ -17,6 +17,8 @@ import java.net.URL;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
import org.openhab.binding.neeo.internal.models.ExecuteResult;
|
import org.openhab.binding.neeo.internal.models.ExecuteResult;
|
||||||
|
@ -44,7 +46,10 @@ public class NeeoBrainApi implements AutoCloseable {
|
||||||
private final Gson gson = NeeoUtil.getGson();
|
private final Gson gson = NeeoUtil.getGson();
|
||||||
|
|
||||||
/** The {@link HttpRequest} used for making requests */
|
/** The {@link HttpRequest} used for making requests */
|
||||||
private final AtomicReference<HttpRequest> request = new AtomicReference<>(new HttpRequest());
|
private final AtomicReference<HttpRequest> request;
|
||||||
|
|
||||||
|
/** The {@link ClientBuilder} to use */
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/** The IP address of the neeo brain */
|
/** The IP address of the neeo brain */
|
||||||
private final NeeoUrlBuilder urlBuilder;
|
private final NeeoUrlBuilder urlBuilder;
|
||||||
|
@ -54,11 +59,14 @@ public class NeeoBrainApi implements AutoCloseable {
|
||||||
*
|
*
|
||||||
* @param ipAddress the non-empty ip address
|
* @param ipAddress the non-empty ip address
|
||||||
*/
|
*/
|
||||||
public NeeoBrainApi(String ipAddress) {
|
public NeeoBrainApi(String ipAddress, ClientBuilder clientBuilder) {
|
||||||
NeeoUtil.requireNotEmpty(ipAddress, "ipAddress cannot be empty");
|
NeeoUtil.requireNotEmpty(ipAddress, "ipAddress cannot be empty");
|
||||||
|
|
||||||
this.urlBuilder = new NeeoUrlBuilder(
|
this.urlBuilder = new NeeoUrlBuilder(
|
||||||
NeeoConstants.PROTOCOL + ipAddress + ":" + NeeoConstants.DEFAULT_BRAIN_PORT);
|
NeeoConstants.PROTOCOL + ipAddress + ":" + NeeoConstants.DEFAULT_BRAIN_PORT);
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
|
|
||||||
|
request = new AtomicReference<>(new HttpRequest(clientBuilder));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -232,7 +240,7 @@ public class NeeoBrainApi implements AutoCloseable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws Exception {
|
public void close() throws Exception {
|
||||||
NeeoUtil.close(request.getAndSet(new HttpRequest()));
|
NeeoUtil.close(request.getAndSet(new HttpRequest(clientBuilder)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.concurrent.locks.ReadWriteLock;
|
||||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
@ -73,6 +74,9 @@ public class NeeoBrainHandler extends BaseBridgeHandler {
|
||||||
/** The {@link NetworkAddressService} to use */
|
/** The {@link NetworkAddressService} to use */
|
||||||
private final NetworkAddressService networkAddressService;
|
private final NetworkAddressService networkAddressService;
|
||||||
|
|
||||||
|
/** The {@link ClientBuilder} to use */
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/** GSON implementation - only used to deserialize {@link NeeoAction} */
|
/** GSON implementation - only used to deserialize {@link NeeoAction} */
|
||||||
private final Gson gson = new Gson();
|
private final Gson gson = new Gson();
|
||||||
|
|
||||||
|
@ -112,7 +116,7 @@ public class NeeoBrainHandler extends BaseBridgeHandler {
|
||||||
* @param networkAddressService the non-null {@link NetworkAddressService}
|
* @param networkAddressService the non-null {@link NetworkAddressService}
|
||||||
*/
|
*/
|
||||||
NeeoBrainHandler(Bridge bridge, int servicePort, HttpService httpService,
|
NeeoBrainHandler(Bridge bridge, int servicePort, HttpService httpService,
|
||||||
NetworkAddressService networkAddressService) {
|
NetworkAddressService networkAddressService, ClientBuilder clientBuilder) {
|
||||||
super(bridge);
|
super(bridge);
|
||||||
|
|
||||||
Objects.requireNonNull(bridge, "bridge cannot be null");
|
Objects.requireNonNull(bridge, "bridge cannot be null");
|
||||||
|
@ -122,6 +126,7 @@ public class NeeoBrainHandler extends BaseBridgeHandler {
|
||||||
this.servicePort = servicePort;
|
this.servicePort = servicePort;
|
||||||
this.httpService = httpService;
|
this.httpService = httpService;
|
||||||
this.networkAddressService = networkAddressService;
|
this.networkAddressService = networkAddressService;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -164,7 +169,7 @@ public class NeeoBrainHandler extends BaseBridgeHandler {
|
||||||
"Brain IP Address must be specified");
|
"Brain IP Address must be specified");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final NeeoBrainApi api = new NeeoBrainApi(ipAddress);
|
final NeeoBrainApi api = new NeeoBrainApi(ipAddress, clientBuilder);
|
||||||
final NeeoBrain brain = api.getBrain();
|
final NeeoBrain brain = api.getBrain();
|
||||||
final String brainId = getNeeoBrainId();
|
final String brainId = getNeeoBrainId();
|
||||||
|
|
||||||
|
@ -184,10 +189,7 @@ public class NeeoBrainHandler extends BaseBridgeHandler {
|
||||||
if (config.isEnableForwardActions()) {
|
if (config.isEnableForwardActions()) {
|
||||||
NeeoUtil.checkInterrupt();
|
NeeoUtil.checkInterrupt();
|
||||||
|
|
||||||
forwardActionServlet = new NeeoForwardActionsServlet(scheduler,
|
forwardActionServlet = new NeeoForwardActionsServlet(scheduler, json -> {
|
||||||
new NeeoForwardActionsServlet.Callback() {
|
|
||||||
@Override
|
|
||||||
public void post(String json) {
|
|
||||||
triggerChannel(NeeoConstants.CHANNEL_BRAIN_FOWARDACTIONS, json);
|
triggerChannel(NeeoConstants.CHANNEL_BRAIN_FOWARDACTIONS, json);
|
||||||
|
|
||||||
final NeeoAction action = Objects.requireNonNull(gson.fromJson(json, NeeoAction.class));
|
final NeeoAction action = Objects.requireNonNull(gson.fromJson(json, NeeoAction.class));
|
||||||
|
@ -198,8 +200,7 @@ public class NeeoBrainHandler extends BaseBridgeHandler {
|
||||||
((NeeoRoomHandler) th).processAction(action);
|
((NeeoRoomHandler) th).processAction(action);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, config.getForwardChain(), clientBuilder);
|
||||||
}, config.getForwardChain());
|
|
||||||
|
|
||||||
NeeoUtil.checkInterrupt();
|
NeeoUtil.checkInterrupt();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -16,13 +16,12 @@ import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServlet;
|
import javax.servlet.http.HttpServlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
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.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
@ -52,6 +51,9 @@ public class NeeoForwardActionsServlet extends HttpServlet {
|
||||||
@Nullable
|
@Nullable
|
||||||
private final String forwardChain;
|
private final String forwardChain;
|
||||||
|
|
||||||
|
/** The {@link ClientBuilder} to use */
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/** The scheduler to use to schedule recipe execution */
|
/** The scheduler to use to schedule recipe execution */
|
||||||
private final ScheduledExecutorService scheduler;
|
private final ScheduledExecutorService scheduler;
|
||||||
|
|
||||||
|
@ -62,7 +64,8 @@ public class NeeoForwardActionsServlet extends HttpServlet {
|
||||||
* @param callback a non-null {@link Callback}
|
* @param callback a non-null {@link Callback}
|
||||||
* @param forwardChain a possibly null, possibly empty forwarding chain
|
* @param forwardChain a possibly null, possibly empty forwarding chain
|
||||||
*/
|
*/
|
||||||
NeeoForwardActionsServlet(ScheduledExecutorService scheduler, Callback callback, @Nullable String forwardChain) {
|
NeeoForwardActionsServlet(ScheduledExecutorService scheduler, Callback callback, @Nullable String forwardChain,
|
||||||
|
ClientBuilder clientBuilder) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
Objects.requireNonNull(scheduler, "scheduler cannot be null");
|
Objects.requireNonNull(scheduler, "scheduler cannot be null");
|
||||||
|
@ -71,6 +74,7 @@ public class NeeoForwardActionsServlet extends HttpServlet {
|
||||||
this.scheduler = scheduler;
|
this.scheduler = scheduler;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
this.forwardChain = forwardChain;
|
this.forwardChain = forwardChain;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -81,10 +85,11 @@ public class NeeoForwardActionsServlet extends HttpServlet {
|
||||||
* @param resp the non-null response
|
* @param resp the non-null response
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doPost(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp)
|
protected void doPost(@Nullable HttpServletRequest req, @Nullable HttpServletResponse resp) throws IOException {
|
||||||
throws ServletException, IOException {
|
if (req == null || resp == null) {
|
||||||
Objects.requireNonNull(req, "req cannot be null");
|
logger.warn("doPost called with req={}, resp={}, non-null required.", req, resp);
|
||||||
Objects.requireNonNull(resp, "resp cannot be null");
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final String json = IOUtils.toString(req.getReader());
|
final String json = IOUtils.toString(req.getReader());
|
||||||
logger.debug("handleForwardActions {}", json);
|
logger.debug("handleForwardActions {}", json);
|
||||||
|
@ -92,11 +97,11 @@ public class NeeoForwardActionsServlet extends HttpServlet {
|
||||||
callback.post(json);
|
callback.post(json);
|
||||||
|
|
||||||
final String fc = forwardChain;
|
final String fc = forwardChain;
|
||||||
if (fc != null && StringUtils.isNotEmpty(fc)) {
|
if (fc != null && !fc.isEmpty()) {
|
||||||
scheduler.execute(() -> {
|
scheduler.execute(() -> {
|
||||||
try (final HttpRequest request = new HttpRequest()) {
|
try (final HttpRequest request = new HttpRequest(clientBuilder)) {
|
||||||
for (final String forwardUrl : fc.split(",")) {
|
for (final String forwardUrl : fc.split(",")) {
|
||||||
if (StringUtils.isNotEmpty(forwardUrl)) {
|
if (forwardUrl != null && !forwardUrl.isEmpty()) {
|
||||||
final HttpResponse httpResponse = request.sendPostJsonCommand(forwardUrl, json);
|
final HttpResponse httpResponse = request.sendPostJsonCommand(forwardUrl, json);
|
||||||
if (httpResponse.getHttpCode() != HttpStatus.OK_200) {
|
if (httpResponse.getHttpCode() != HttpStatus.OK_200) {
|
||||||
logger.debug("Cannot forward event {} to {}: {}", json, forwardUrl,
|
logger.debug("Cannot forward event {} to {}: {}", json, forwardUrl,
|
||||||
|
|
|
@ -17,6 +17,8 @@ import java.util.Objects;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
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.binding.neeo.internal.NeeoConstants;
|
import org.openhab.binding.neeo.internal.NeeoConstants;
|
||||||
|
@ -33,6 +35,7 @@ import org.openhab.core.thing.binding.BaseThingHandlerFactory;
|
||||||
import org.openhab.core.thing.binding.ThingHandler;
|
import org.openhab.core.thing.binding.ThingHandler;
|
||||||
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
import org.openhab.core.thing.binding.ThingHandlerFactory;
|
||||||
import org.osgi.framework.ServiceRegistration;
|
import org.osgi.framework.ServiceRegistration;
|
||||||
|
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.Reference;
|
import org.osgi.service.component.annotations.Reference;
|
||||||
import org.osgi.service.http.HttpService;
|
import org.osgi.service.http.HttpService;
|
||||||
|
@ -48,54 +51,23 @@ import org.osgi.service.http.HttpService;
|
||||||
public class NeeoHandlerFactory extends BaseThingHandlerFactory {
|
public class NeeoHandlerFactory extends BaseThingHandlerFactory {
|
||||||
|
|
||||||
/** The {@link HttpService} used to register callbacks */
|
/** The {@link HttpService} used to register callbacks */
|
||||||
@NonNullByDefault({})
|
private final HttpService httpService;
|
||||||
private HttpService httpService;
|
|
||||||
|
|
||||||
/** The {@link NetworkAddressService} used for ip lookup */
|
/** The {@link NetworkAddressService} used for ip lookup */
|
||||||
@NonNullByDefault({})
|
private final NetworkAddressService networkAddressService;
|
||||||
private NetworkAddressService networkAddressService;
|
|
||||||
|
/** The {@link ClientBuilder} used in HttpRequest */
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/** The discovery services created by this class (one per room and one for each device) */
|
/** The discovery services created by this class (one per room and one for each device) */
|
||||||
private final ConcurrentMap<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new ConcurrentHashMap<>();
|
private final ConcurrentMap<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
/**
|
@Activate
|
||||||
* Sets the {@link HttpService}.
|
public NeeoHandlerFactory(@Reference HttpService httpService,
|
||||||
*
|
@Reference NetworkAddressService networkAddressService, @Reference ClientBuilder clientBuilder) {
|
||||||
* @param httpService the non-null {@link HttpService} to use
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
protected void setHttpService(HttpService httpService) {
|
|
||||||
Objects.requireNonNull(httpService, "httpService cannot be null");
|
|
||||||
this.httpService = httpService;
|
this.httpService = httpService;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsets the {@link HttpService}
|
|
||||||
*
|
|
||||||
* @param httpService the {@link HttpService} (not used in this implementation)
|
|
||||||
*/
|
|
||||||
protected void unsetHttpService(HttpService httpService) {
|
|
||||||
this.httpService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the {@link NetworkAddressService}.
|
|
||||||
*
|
|
||||||
* @param networkAddressService the non-null {@link NetworkAddressService} to use
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
protected void setNetworkAddressService(NetworkAddressService networkAddressService) {
|
|
||||||
Objects.requireNonNull(networkAddressService, "networkAddressService cannot be null");
|
|
||||||
this.networkAddressService = networkAddressService;
|
this.networkAddressService = networkAddressService;
|
||||||
}
|
this.clientBuilder = clientBuilder;
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsets the {@link NetworkAddressService}
|
|
||||||
*
|
|
||||||
* @param networkAddressService the {@link NetworkAddressService} (not used in this implementation)
|
|
||||||
*/
|
|
||||||
protected void unsetNetworkAddressService(NetworkAddressService networkAddressService) {
|
|
||||||
this.networkAddressService = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -112,17 +84,10 @@ public class NeeoHandlerFactory extends BaseThingHandlerFactory {
|
||||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||||
|
|
||||||
if (thingTypeUID.equals(NeeoConstants.BRIDGE_TYPE_BRAIN)) {
|
if (thingTypeUID.equals(NeeoConstants.BRIDGE_TYPE_BRAIN)) {
|
||||||
final HttpService localHttpService = httpService;
|
|
||||||
final NetworkAddressService localNetworkAddressService = networkAddressService;
|
|
||||||
|
|
||||||
Objects.requireNonNull(localHttpService, "HttpService cannot be null");
|
|
||||||
Objects.requireNonNull(localNetworkAddressService, "networkAddressService cannot be null");
|
|
||||||
|
|
||||||
final int port = HttpServiceUtil.getHttpServicePort(this.bundleContext);
|
final int port = HttpServiceUtil.getHttpServicePort(this.bundleContext);
|
||||||
|
|
||||||
final NeeoBrainHandler handler = new NeeoBrainHandler((Bridge) thing,
|
final NeeoBrainHandler handler = new NeeoBrainHandler((Bridge) thing,
|
||||||
port < 0 ? NeeoConstants.DEFAULT_BRAIN_HTTP_PORT : port, localHttpService,
|
port < 0 ? NeeoConstants.DEFAULT_BRAIN_HTTP_PORT : port, httpService, networkAddressService,
|
||||||
localNetworkAddressService);
|
clientBuilder);
|
||||||
registerRoomDiscoveryService(handler);
|
registerRoomDiscoveryService(handler);
|
||||||
return handler;
|
return handler;
|
||||||
} else if (thingTypeUID.equals(NeeoConstants.BRIDGE_TYPE_ROOM)) {
|
} else if (thingTypeUID.equals(NeeoConstants.BRIDGE_TYPE_ROOM)) {
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
package org.openhab.binding.neeo.internal.net;
|
package org.openhab.binding.neeo.internal.net;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import javax.ws.rs.ProcessingException;
|
import javax.ws.rs.ProcessingException;
|
||||||
|
@ -47,8 +49,8 @@ public class HttpRequest implements AutoCloseable {
|
||||||
/**
|
/**
|
||||||
* Instantiates a new request
|
* Instantiates a new request
|
||||||
*/
|
*/
|
||||||
public HttpRequest() {
|
public HttpRequest(ClientBuilder clientBuilder) {
|
||||||
client = ClientBuilder.newClient();
|
client = clientBuilder.build();
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
client.register(new LoggingFilter(new Slf4LoggingAdapter(logger), true));
|
client.register(new LoggingFilter(new Slf4LoggingAdapter(logger), true));
|
||||||
|
@ -81,16 +83,23 @@ public class HttpRequest implements AutoCloseable {
|
||||||
/**
|
/**
|
||||||
* Send post JSON command using the body
|
* Send post JSON command using the body
|
||||||
*
|
*
|
||||||
* @param uri the non empty uri
|
* @param uriString the non empty uri
|
||||||
* @param body the non-null, possibly empty body
|
* @param body the non-null, possibly empty body
|
||||||
* @return the {@link HttpResponse}
|
* @return the {@link HttpResponse}
|
||||||
*/
|
*/
|
||||||
public HttpResponse sendPostJsonCommand(String uri, String body) {
|
public HttpResponse sendPostJsonCommand(String uriString, String body) {
|
||||||
NeeoUtil.requireNotEmpty(uri, "uri cannot be empty");
|
NeeoUtil.requireNotEmpty(uriString, "uri cannot be empty");
|
||||||
Objects.requireNonNull(body, "body cannot be null");
|
Objects.requireNonNull(body, "body cannot be null");
|
||||||
|
|
||||||
|
logger.trace("sendPostJsonCommand: target={}, body={}", uriString, body);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Builder request = client.target(uri).request(MediaType.APPLICATION_JSON);
|
URI targetUri = new URI(uriString);
|
||||||
|
if (!targetUri.isAbsolute()) {
|
||||||
|
logger.warn("Absolute URI required but provided URI '{}' is non-absolute. ", uriString);
|
||||||
|
return new HttpResponse(HttpStatus.NOT_ACCEPTABLE_406, "Absolute URI required");
|
||||||
|
}
|
||||||
|
final Builder request = client.target(targetUri).request(MediaType.APPLICATION_JSON);
|
||||||
|
|
||||||
final Response content = request.post(Entity.entity(body, MediaType.APPLICATION_JSON));
|
final Response content = request.post(Entity.entity(body, MediaType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
@ -103,6 +112,8 @@ public class HttpRequest implements AutoCloseable {
|
||||||
// as well
|
// as well
|
||||||
} catch (IOException | IllegalStateException | IllegalArgumentException | ProcessingException e) {
|
} catch (IOException | IllegalStateException | IllegalArgumentException | ProcessingException e) {
|
||||||
return new HttpResponse(HttpStatus.SERVICE_UNAVAILABLE_503, e.getMessage());
|
return new HttpResponse(HttpStatus.SERVICE_UNAVAILABLE_503, e.getMessage());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
return new HttpResponse(HttpStatus.NOT_ACCEPTABLE_406, e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
@ -82,19 +83,20 @@ public class NeeoService implements EventSubscriber, NetworkAddressChangeListene
|
||||||
* This is the context created in the activate method (and nulled in the deactivate method) that will provide the
|
* This is the context created in the activate method (and nulled in the deactivate method) that will provide the
|
||||||
* context to all services for all servlets
|
* context to all services for all servlets
|
||||||
*/
|
*/
|
||||||
private @Nullable ServiceContext context;
|
private final ServiceContext context;
|
||||||
|
|
||||||
// The following services are set by openHAB via the getter/setters
|
// The following services are set by openHAB via the getter/setters
|
||||||
private @Nullable HttpService httpService;
|
private final HttpService httpService;
|
||||||
private @Nullable ItemRegistry itemRegistry;
|
private final ItemRegistry itemRegistry;
|
||||||
private @Nullable BindingInfoRegistry bindingInfoRegistry;
|
private final BindingInfoRegistry bindingInfoRegistry;
|
||||||
private @Nullable ThingRegistry thingRegistry;
|
private final ThingRegistry thingRegistry;
|
||||||
private @Nullable ThingTypeRegistry thingTypeRegistry;
|
private final ThingTypeRegistry thingTypeRegistry;
|
||||||
private @Nullable ItemChannelLinkRegistry itemChannelLinkRegistry;
|
private final ItemChannelLinkRegistry itemChannelLinkRegistry;
|
||||||
private @Nullable ChannelTypeRegistry channelTypeRegistry;
|
private final ChannelTypeRegistry channelTypeRegistry;
|
||||||
private @Nullable MDNSClient mdnsClient;
|
private final MDNSClient mdnsClient;
|
||||||
private @Nullable EventPublisher eventPublisher;
|
private final EventPublisher eventPublisher;
|
||||||
private @Nullable NetworkAddressService networkAddressService;
|
private final NetworkAddressService networkAddressService;
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/** The main dashboard servlet. Only created in the activate method (and disposed of in the deactivate method) */
|
/** The main dashboard servlet. Only created in the activate method (and disposed of in the deactivate method) */
|
||||||
private @Nullable NeeoDashboardServlet dashboardServlet;
|
private @Nullable NeeoDashboardServlet dashboardServlet;
|
||||||
|
@ -136,238 +138,24 @@ public class NeeoService implements EventSubscriber, NetworkAddressChangeListene
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The event filter to apply to this service
|
|
||||||
*/
|
|
||||||
private final EventFilter eventFilter = event -> {
|
|
||||||
logger.trace("apply: {}", event);
|
|
||||||
|
|
||||||
for (NeeoBrainServlet ns : servlets) {
|
|
||||||
final List<EventFilter> efs = ns.getEventFilters();
|
|
||||||
if (efs != null) {
|
|
||||||
for (EventFilter ef : efs) {
|
|
||||||
if (ef.apply(event)) {
|
|
||||||
logger.trace("apply (true): {}", event);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.trace("apply (false): {}", event);
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the http service.
|
|
||||||
*
|
|
||||||
* @param httpService the non-null http service
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setHttpService(HttpService httpService) {
|
|
||||||
Objects.requireNonNull(httpService, "httpService cannot be null");
|
|
||||||
this.httpService = httpService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset http service.
|
|
||||||
*
|
|
||||||
* @param httpService the http service (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetHttpService(HttpService httpService) {
|
|
||||||
this.httpService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the item registry.
|
|
||||||
*
|
|
||||||
* @param itemRegistry the non-null item registry
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setItemRegistry(ItemRegistry itemRegistry) {
|
|
||||||
Objects.requireNonNull(itemRegistry, "itemRegistry cannot be null");
|
|
||||||
this.itemRegistry = itemRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset item registry.
|
|
||||||
*
|
|
||||||
* @param itemRegistry the item registry (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetItemRegistry(ItemRegistry itemRegistry) {
|
|
||||||
this.itemRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the binding info registry.
|
|
||||||
*
|
|
||||||
* @param bindingInfoRegistry the non-null binding info registry
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setBindingInfoRegistry(BindingInfoRegistry bindingInfoRegistry) {
|
|
||||||
Objects.requireNonNull(bindingInfoRegistry, "bindingInfoRegistry cannot be null");
|
|
||||||
this.bindingInfoRegistry = bindingInfoRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset binding info registry.
|
|
||||||
*
|
|
||||||
* @param bindingInfoRegistry the binding info registry (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetBindingInfoRegistry(BindingInfoRegistry bindingInfoRegistry) {
|
|
||||||
this.bindingInfoRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the thing registry.
|
|
||||||
*
|
|
||||||
* @param thingRegistry the non-null thing registry
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setThingRegistry(ThingRegistry thingRegistry) {
|
|
||||||
Objects.requireNonNull(thingRegistry, "thingRegistry cannot be null");
|
|
||||||
this.thingRegistry = thingRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset thing registry.
|
|
||||||
*
|
|
||||||
* @param thingRegistry the thing registry (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetThingRegistry(ThingRegistry thingRegistry) {
|
|
||||||
this.thingRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the thing type registry.
|
|
||||||
*
|
|
||||||
* @param thingTypeRegistry the non-null thing type registry
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setThingTypeRegistry(ThingTypeRegistry thingTypeRegistry) {
|
|
||||||
Objects.requireNonNull(thingTypeRegistry, "thingTypeRegistry cannot be null");
|
|
||||||
this.thingTypeRegistry = thingTypeRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset thing type registry.
|
|
||||||
*
|
|
||||||
* @param thingTypeRegistry the thing type registry (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetThingTypeRegistry(ThingTypeRegistry thingTypeRegistry) {
|
|
||||||
this.thingTypeRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the item channel link registry.
|
|
||||||
*
|
|
||||||
* @param itemChannelLinkRegistry the non-null item channel link registry
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
|
||||||
Objects.requireNonNull(itemChannelLinkRegistry, "itemChannelLinkRegistry cannot be null");
|
|
||||||
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset item channel link registry.
|
|
||||||
*
|
|
||||||
* @param itemChannelLinkRegistry the item channel link registry (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetItemChannelLinkRegistry(ItemChannelLinkRegistry itemChannelLinkRegistry) {
|
|
||||||
this.itemChannelLinkRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the channel type registry.
|
|
||||||
*
|
|
||||||
* @param channelTypeRegistry the non-null channel type registry
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setChannelTypeRegistry(ChannelTypeRegistry channelTypeRegistry) {
|
|
||||||
Objects.requireNonNull(channelTypeRegistry, "channelTypeRegistry cannot be null");
|
|
||||||
this.channelTypeRegistry = channelTypeRegistry;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset channel type registry.
|
|
||||||
*
|
|
||||||
* @param channelTypeRegistry the channel type registry (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetChannelTypeRegistry(ChannelTypeRegistry channelTypeRegistry) {
|
|
||||||
this.channelTypeRegistry = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the MDNS client.
|
|
||||||
*
|
|
||||||
* @param mdnsClient the non-null MDNS client
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setMDNSClient(MDNSClient mdnsClient) {
|
|
||||||
Objects.requireNonNull(mdnsClient, "mdnsClient cannot be null");
|
|
||||||
this.mdnsClient = mdnsClient;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset MDNS client.
|
|
||||||
*
|
|
||||||
* @param mdnsClient the mdns client (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetMDNSClient(MDNSClient mdnsClient) {
|
|
||||||
this.mdnsClient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the event publisher.
|
|
||||||
*
|
|
||||||
* @param eventPublisher the new event publisher
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
Objects.requireNonNull(eventPublisher, "eventPublisher cannot be null");
|
|
||||||
this.eventPublisher = eventPublisher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unset event publisher.
|
|
||||||
*
|
|
||||||
* @param eventPublisher the event publisher (ignored)
|
|
||||||
*/
|
|
||||||
public void unsetEventPublisher(EventPublisher eventPublisher) {
|
|
||||||
this.eventPublisher = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the network address service
|
|
||||||
*
|
|
||||||
* @param networkAddressService the network address service
|
|
||||||
*/
|
|
||||||
@Reference
|
|
||||||
public void setNetworkAddressService(NetworkAddressService networkAddressService) {
|
|
||||||
Objects.requireNonNull(networkAddressService, "networkAddressService cannot be null");
|
|
||||||
this.networkAddressService = networkAddressService;
|
|
||||||
networkAddressService.addNetworkAddressChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsets network address service
|
|
||||||
*
|
|
||||||
* @param networkAddressService address service
|
|
||||||
*/
|
|
||||||
public void unsetNetworkAddressService(NetworkAddressService networkAddressService) {
|
|
||||||
networkAddressService.removeNetworkAddressChangeListener(this);
|
|
||||||
this.networkAddressService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Activates this service. The activation will start up the brain discovery service and register the dashboard tile
|
|
||||||
*
|
|
||||||
* @param componentContext the non-null component context
|
|
||||||
*/
|
|
||||||
@Activate
|
@Activate
|
||||||
public void activate(final ComponentContext componentContext) {
|
public NeeoService(ComponentContext componentContext, @Reference HttpService httpService,
|
||||||
Objects.requireNonNull(componentContext, "componentContext cannot be null");
|
@Reference ItemRegistry itemRegistry, @Reference ThingRegistry thingRegistry,
|
||||||
|
@Reference BindingInfoRegistry bindingInfoRegistry, @Reference ChannelTypeRegistry channelTypeRegistry,
|
||||||
|
@Reference ThingTypeRegistry thingTypeRegistry, @Reference ItemChannelLinkRegistry itemChannelLinkRegistry,
|
||||||
|
@Reference MDNSClient mdnsClient, @Reference EventPublisher eventPublisher,
|
||||||
|
@Reference NetworkAddressService networkAddressService, @Reference ClientBuilder clientBuilder) {
|
||||||
|
this.httpService = httpService;
|
||||||
|
this.itemRegistry = itemRegistry;
|
||||||
|
this.bindingInfoRegistry = bindingInfoRegistry;
|
||||||
|
this.channelTypeRegistry = channelTypeRegistry;
|
||||||
|
this.thingRegistry = thingRegistry;
|
||||||
|
this.thingTypeRegistry = thingTypeRegistry;
|
||||||
|
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
|
||||||
|
this.mdnsClient = mdnsClient;
|
||||||
|
this.eventPublisher = eventPublisher;
|
||||||
|
this.networkAddressService = networkAddressService;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
|
|
||||||
logger.debug("Neeo Service activated");
|
logger.debug("Neeo Service activated");
|
||||||
final ServiceContext localContext = new ServiceContext(componentContext, validate(httpService, "httpService"),
|
final ServiceContext localContext = new ServiceContext(componentContext, validate(httpService, "httpService"),
|
||||||
|
@ -378,7 +166,7 @@ public class NeeoService implements EventSubscriber, NetworkAddressChangeListene
|
||||||
validate(eventPublisher, "eventPublisher"), validate(networkAddressService, "networkAddressService"));
|
validate(eventPublisher, "eventPublisher"), validate(networkAddressService, "networkAddressService"));
|
||||||
|
|
||||||
context = localContext;
|
context = localContext;
|
||||||
discovery = new MdnsBrainDiscovery(localContext);
|
discovery = new MdnsBrainDiscovery(localContext, clientBuilder);
|
||||||
discovery.addListener(discoveryListener);
|
discovery.addListener(discoveryListener);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -402,6 +190,28 @@ public class NeeoService implements EventSubscriber, NetworkAddressChangeListene
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The event filter to apply to this service
|
||||||
|
*/
|
||||||
|
private final EventFilter eventFilter = event -> {
|
||||||
|
logger.trace("apply: {}", event);
|
||||||
|
|
||||||
|
for (NeeoBrainServlet ns : servlets) {
|
||||||
|
final List<EventFilter> efs = ns.getEventFilters();
|
||||||
|
if (efs != null) {
|
||||||
|
for (EventFilter ef : efs) {
|
||||||
|
if (ef.apply(event)) {
|
||||||
|
logger.trace("apply (true): {}", event);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.trace("apply (false): {}", event);
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to validate that the specific item wasn't null and convert it's type to a non-nullable type
|
* Helper method to validate that the specific item wasn't null and convert it's type to a non-nullable type
|
||||||
*
|
*
|
||||||
|
@ -441,8 +251,6 @@ public class NeeoService implements EventSubscriber, NetworkAddressChangeListene
|
||||||
NeeoUtil.close(servlet);
|
NeeoUtil.close(servlet);
|
||||||
}
|
}
|
||||||
servlets.clear();
|
servlets.clear();
|
||||||
|
|
||||||
context = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dashboardServlet != null) {
|
if (dashboardServlet != null) {
|
||||||
|
@ -472,7 +280,7 @@ public class NeeoService implements EventSubscriber, NetworkAddressChangeListene
|
||||||
servletUrl);
|
servletUrl);
|
||||||
try {
|
try {
|
||||||
final NeeoBrainServlet newServlet = NeeoBrainServlet.create(localContext, servletUrl,
|
final NeeoBrainServlet newServlet = NeeoBrainServlet.create(localContext, servletUrl,
|
||||||
sysInfo.getHostname(), ipAddress);
|
sysInfo.getHostname(), ipAddress, clientBuilder);
|
||||||
servlets.add(newServlet);
|
servlets.add(newServlet);
|
||||||
|
|
||||||
localContext.getHttpService().registerServlet(servletUrl, newServlet, new Hashtable<>(),
|
localContext.getHttpService().registerServlet(servletUrl, newServlet, new Hashtable<>(),
|
||||||
|
|
|
@ -27,6 +27,8 @@ import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -68,6 +70,8 @@ public class NeeoApi implements AutoCloseable {
|
||||||
/** The brain's IP address */
|
/** The brain's IP address */
|
||||||
private final String brainIpAddress;
|
private final String brainIpAddress;
|
||||||
|
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/** The URL of the brain */
|
/** The URL of the brain */
|
||||||
private final String brainUrl;
|
private final String brainUrl;
|
||||||
|
|
||||||
|
@ -107,8 +111,7 @@ public class NeeoApi implements AutoCloseable {
|
||||||
private final AtomicReference<@Nullable ScheduledFuture<?>> checkStatus = new AtomicReference<>(null);
|
private final AtomicReference<@Nullable ScheduledFuture<?>> checkStatus = new AtomicReference<>(null);
|
||||||
|
|
||||||
/** The {@link HttpRequest} used for making requests */
|
/** The {@link HttpRequest} used for making requests */
|
||||||
private final AtomicReference<HttpRequest> request = new AtomicReference<>(new HttpRequest());
|
private final AtomicReference<HttpRequest> request;
|
||||||
|
|
||||||
/** Whether the brain is currently connected */
|
/** Whether the brain is currently connected */
|
||||||
private final AtomicBoolean connected = new AtomicBoolean(false);
|
private final AtomicBoolean connected = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
@ -120,21 +123,25 @@ public class NeeoApi implements AutoCloseable {
|
||||||
* @param context the non-null {@link ServiceContext}
|
* @param context the non-null {@link ServiceContext}
|
||||||
* @throws IOException if an exception occurs connecting to the brain
|
* @throws IOException if an exception occurs connecting to the brain
|
||||||
*/
|
*/
|
||||||
public NeeoApi(String ipAddress, String brainId, ServiceContext context) throws IOException {
|
public NeeoApi(String ipAddress, String brainId, ServiceContext context, ClientBuilder clientBuilder)
|
||||||
|
throws IOException {
|
||||||
NeeoUtil.requireNotEmpty(ipAddress, "ipAddress cannot be empty");
|
NeeoUtil.requireNotEmpty(ipAddress, "ipAddress cannot be empty");
|
||||||
NeeoUtil.requireNotEmpty(brainId, "brainId cannot be empty");
|
NeeoUtil.requireNotEmpty(brainId, "brainId cannot be empty");
|
||||||
Objects.requireNonNull(context, "context cannot be null");
|
Objects.requireNonNull(context, "context cannot be null");
|
||||||
|
|
||||||
this.brainIpAddress = ipAddress;
|
this.brainIpAddress = ipAddress;
|
||||||
this.brainId = brainId;
|
this.brainId = brainId;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
this.brainUrl = NeeoConstants.PROTOCOL + (ipAddress.startsWith("/") ? ipAddress.substring(1) : ipAddress) + ":"
|
this.brainUrl = NeeoConstants.PROTOCOL + (ipAddress.startsWith("/") ? ipAddress.substring(1) : ipAddress) + ":"
|
||||||
+ NeeoConstants.DEFAULT_BRAIN_PORT;
|
+ NeeoConstants.DEFAULT_BRAIN_PORT;
|
||||||
deviceKeys = new NeeoDeviceKeys(brainUrl);
|
deviceKeys = new NeeoDeviceKeys(brainUrl, clientBuilder);
|
||||||
|
|
||||||
this.systemInfo = getSystemInfo(ipAddress);
|
request = new AtomicReference<>(new HttpRequest(clientBuilder));
|
||||||
|
|
||||||
|
this.systemInfo = getSystemInfo(ipAddress, clientBuilder);
|
||||||
|
|
||||||
String name = brainId;
|
String name = brainId;
|
||||||
try (HttpRequest request = new HttpRequest()) {
|
try (HttpRequest request = new HttpRequest(clientBuilder)) {
|
||||||
logger.debug("Getting existing device mappings from {}{}", brainUrl, NeeoConstants.PROJECTS_HOME);
|
logger.debug("Getting existing device mappings from {}{}", brainUrl, NeeoConstants.PROJECTS_HOME);
|
||||||
final HttpResponse resp = request.sendGetCommand(brainUrl + NeeoConstants.PROJECTS_HOME);
|
final HttpResponse resp = request.sendGetCommand(brainUrl + NeeoConstants.PROJECTS_HOME);
|
||||||
if (resp.getHttpCode() != HttpStatus.OK_200) {
|
if (resp.getHttpCode() != HttpStatus.OK_200) {
|
||||||
|
@ -196,12 +203,12 @@ public class NeeoApi implements AutoCloseable {
|
||||||
* @return the non-null {@link NeeoSystemInfo} for the address
|
* @return the non-null {@link NeeoSystemInfo} for the address
|
||||||
* @throws IOException Signals that an I/O exception has occurred or the URL is not a brain
|
* @throws IOException Signals that an I/O exception has occurred or the URL is not a brain
|
||||||
*/
|
*/
|
||||||
public static NeeoSystemInfo getSystemInfo(String ipAddress) throws IOException {
|
public static NeeoSystemInfo getSystemInfo(String ipAddress, ClientBuilder clientBuilder) throws IOException {
|
||||||
NeeoUtil.requireNotEmpty(ipAddress, "ipAddress cannot be empty");
|
NeeoUtil.requireNotEmpty(ipAddress, "ipAddress cannot be empty");
|
||||||
final String sysInfo = NeeoConstants.PROTOCOL + (ipAddress.startsWith("/") ? ipAddress.substring(1) : ipAddress)
|
final String sysInfo = NeeoConstants.PROTOCOL + (ipAddress.startsWith("/") ? ipAddress.substring(1) : ipAddress)
|
||||||
+ ":" + NeeoConstants.DEFAULT_BRAIN_PORT + NeeoConstants.SYSTEMINFO;
|
+ ":" + NeeoConstants.DEFAULT_BRAIN_PORT + NeeoConstants.SYSTEMINFO;
|
||||||
|
|
||||||
try (HttpRequest req = new HttpRequest()) {
|
try (HttpRequest req = new HttpRequest(clientBuilder)) {
|
||||||
final HttpResponse res = req.sendGetCommand(sysInfo);
|
final HttpResponse res = req.sendGetCommand(sysInfo);
|
||||||
if (res.getHttpCode() == HttpStatus.OK_200) {
|
if (res.getHttpCode() == HttpStatus.OK_200) {
|
||||||
return Objects.requireNonNull(GSON.fromJson(res.getContent(), NeeoSystemInfo.class));
|
return Objects.requireNonNull(GSON.fromJson(res.getContent(), NeeoSystemInfo.class));
|
||||||
|
@ -387,7 +394,7 @@ public class NeeoApi implements AutoCloseable {
|
||||||
try {
|
try {
|
||||||
setConnected(false);
|
setConnected(false);
|
||||||
|
|
||||||
NeeoUtil.close(request.getAndSet(new HttpRequest()));
|
NeeoUtil.close(request.getAndSet(new HttpRequest(clientBuilder)));
|
||||||
|
|
||||||
NeeoUtil.checkInterrupt();
|
NeeoUtil.checkInterrupt();
|
||||||
registerApi();
|
registerApi();
|
||||||
|
|
|
@ -16,6 +16,8 @@ import java.io.IOException;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.openhab.io.neeo.internal.models.BrainStatus;
|
import org.openhab.io.neeo.internal.models.BrainStatus;
|
||||||
import org.openhab.io.neeo.internal.servletservices.NeeoBrainSearchService;
|
import org.openhab.io.neeo.internal.servletservices.NeeoBrainSearchService;
|
||||||
|
@ -44,8 +46,9 @@ public class NeeoBrainServlet extends AbstractServlet {
|
||||||
* @param servletUrl the non-null, non-empty servlet URL
|
* @param servletUrl the non-null, non-empty servlet URL
|
||||||
* @param api the non-null API
|
* @param api the non-null API
|
||||||
*/
|
*/
|
||||||
private NeeoBrainServlet(ServiceContext context, String servletUrl, NeeoApi api) {
|
private NeeoBrainServlet(ServiceContext context, String servletUrl, NeeoApi api, ClientBuilder clientBuilder) {
|
||||||
super(context, servletUrl, new NeeoBrainSearchService(context), new NeeoBrainService(api, context));
|
super(context, servletUrl, new NeeoBrainSearchService(context),
|
||||||
|
new NeeoBrainService(api, context, clientBuilder));
|
||||||
|
|
||||||
Objects.requireNonNull(context, "context cannot be null");
|
Objects.requireNonNull(context, "context cannot be null");
|
||||||
NeeoUtil.requireNotEmpty(servletUrl, "servletUrl cannot be empty");
|
NeeoUtil.requireNotEmpty(servletUrl, "servletUrl cannot be empty");
|
||||||
|
@ -65,16 +68,16 @@ public class NeeoBrainServlet extends AbstractServlet {
|
||||||
* @throws IOException when an exception occurs contacting the brain
|
* @throws IOException when an exception occurs contacting the brain
|
||||||
*/
|
*/
|
||||||
public static NeeoBrainServlet create(ServiceContext context, String servletUrl, String brainId,
|
public static NeeoBrainServlet create(ServiceContext context, String servletUrl, String brainId,
|
||||||
InetAddress ipAddress) throws IOException {
|
InetAddress ipAddress, ClientBuilder clientBuilder) throws IOException {
|
||||||
Objects.requireNonNull(context, "context cannot be null");
|
Objects.requireNonNull(context, "context cannot be null");
|
||||||
NeeoUtil.requireNotEmpty(servletUrl, "servletUrl cannot be empty");
|
NeeoUtil.requireNotEmpty(servletUrl, "servletUrl cannot be empty");
|
||||||
NeeoUtil.requireNotEmpty(brainId, "brainId cannot be empty");
|
NeeoUtil.requireNotEmpty(brainId, "brainId cannot be empty");
|
||||||
Objects.requireNonNull(ipAddress, "ipAddress cannot be null");
|
Objects.requireNonNull(ipAddress, "ipAddress cannot be null");
|
||||||
|
|
||||||
final NeeoApi api = new NeeoApi(ipAddress.getHostAddress(), brainId, context);
|
final NeeoApi api = new NeeoApi(ipAddress.getHostAddress(), brainId, context, clientBuilder);
|
||||||
api.start();
|
api.start();
|
||||||
|
|
||||||
return new NeeoBrainServlet(context, servletUrl, api);
|
return new NeeoBrainServlet(context, servletUrl, api, clientBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,6 +21,8 @@ import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jetty.http.HttpStatus;
|
import org.eclipse.jetty.http.HttpStatus;
|
||||||
|
@ -52,15 +54,18 @@ public class NeeoDeviceKeys {
|
||||||
/** The brain's url */
|
/** The brain's url */
|
||||||
private final String brainUrl;
|
private final String brainUrl;
|
||||||
|
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the object from the context and brainUrl
|
* Creates the object from the context and brainUrl
|
||||||
*
|
*
|
||||||
* @param brainUrl the non-empty brain url
|
* @param brainUrl the non-empty brain url
|
||||||
*/
|
*/
|
||||||
NeeoDeviceKeys(String brainUrl) {
|
NeeoDeviceKeys(String brainUrl, ClientBuilder clientBuilder) {
|
||||||
NeeoUtil.requireNotEmpty(brainUrl, "brainUrl cannot be empty");
|
NeeoUtil.requireNotEmpty(brainUrl, "brainUrl cannot be empty");
|
||||||
|
|
||||||
this.brainUrl = brainUrl;
|
this.brainUrl = brainUrl;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -69,7 +74,7 @@ public class NeeoDeviceKeys {
|
||||||
* @throws IOException Signals that an I/O exception has occurred.
|
* @throws IOException Signals that an I/O exception has occurred.
|
||||||
*/
|
*/
|
||||||
void refresh() throws IOException {
|
void refresh() throws IOException {
|
||||||
try (HttpRequest request = new HttpRequest()) {
|
try (HttpRequest request = new HttpRequest(clientBuilder)) {
|
||||||
logger.debug("Getting existing device mappings from {}{}", brainUrl, NeeoConstants.PROJECTS_HOME);
|
logger.debug("Getting existing device mappings from {}{}", brainUrl, NeeoConstants.PROJECTS_HOME);
|
||||||
final HttpResponse resp = request.sendGetCommand(brainUrl + NeeoConstants.PROJECTS_HOME);
|
final HttpResponse resp = request.sendGetCommand(brainUrl + NeeoConstants.PROJECTS_HOME);
|
||||||
if (resp.getHttpCode() != HttpStatus.OK_200) {
|
if (resp.getHttpCode() != HttpStatus.OK_200) {
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.stream.Collectors;
|
||||||
import javax.jmdns.ServiceEvent;
|
import javax.jmdns.ServiceEvent;
|
||||||
import javax.jmdns.ServiceInfo;
|
import javax.jmdns.ServiceInfo;
|
||||||
import javax.jmdns.ServiceListener;
|
import javax.jmdns.ServiceListener;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
@ -106,14 +107,17 @@ public class MdnsBrainDiscovery extends AbstractBrainDiscovery {
|
||||||
/** The file we store definitions in */
|
/** The file we store definitions in */
|
||||||
private final File file = new File(NeeoConstants.FILENAME_DISCOVEREDBRAINS);
|
private final File file = new File(NeeoConstants.FILENAME_DISCOVEREDBRAINS);
|
||||||
|
|
||||||
|
private final ClientBuilder clientBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the MDNS brain discovery from the given {@link ServiceContext}
|
* Creates the MDNS brain discovery from the given {@link ServiceContext}
|
||||||
*
|
*
|
||||||
* @param context the non-null service context
|
* @param context the non-null service context
|
||||||
*/
|
*/
|
||||||
public MdnsBrainDiscovery(ServiceContext context) {
|
public MdnsBrainDiscovery(ServiceContext context, ClientBuilder clientBuilder) {
|
||||||
Objects.requireNonNull(context, "context cannot be null");
|
Objects.requireNonNull(context, "context cannot be null");
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
this.clientBuilder = clientBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -250,7 +254,7 @@ public class MdnsBrainDiscovery extends AbstractBrainDiscovery {
|
||||||
|
|
||||||
NeeoSystemInfo sysInfo;
|
NeeoSystemInfo sysInfo;
|
||||||
try {
|
try {
|
||||||
sysInfo = NeeoApi.getSystemInfo(brainInfo.getValue().toString());
|
sysInfo = NeeoApi.getSystemInfo(brainInfo.getValue().toString(), clientBuilder);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// We can get an MDNS notification BEFORE the brain is ready to process.
|
// We can get an MDNS notification BEFORE the brain is ready to process.
|
||||||
// if that happens, we'll get an IOException (usually bad gateway message), schedule another attempt to get
|
// if that happens, we'll get an IOException (usually bad gateway message), schedule another attempt to get
|
||||||
|
@ -299,7 +303,7 @@ public class MdnsBrainDiscovery extends AbstractBrainDiscovery {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final InetAddress addr = InetAddress.getByName(ipAddress);
|
final InetAddress addr = InetAddress.getByName(ipAddress);
|
||||||
final NeeoSystemInfo sysInfo = NeeoApi.getSystemInfo(ipAddress);
|
final NeeoSystemInfo sysInfo = NeeoApi.getSystemInfo(ipAddress, clientBuilder);
|
||||||
logger.debug("Manually adding brain ({}) with system information: {}", ipAddress, sysInfo);
|
logger.debug("Manually adding brain ({}) with system information: {}", ipAddress, sysInfo);
|
||||||
|
|
||||||
systemsLock.lock();
|
systemsLock.lock();
|
||||||
|
|
|
@ -47,8 +47,8 @@ public class HttpRequest implements AutoCloseable {
|
||||||
/**
|
/**
|
||||||
* Instantiates a new request
|
* Instantiates a new request
|
||||||
*/
|
*/
|
||||||
public HttpRequest() {
|
public HttpRequest(ClientBuilder clientBuilder) {
|
||||||
client = ClientBuilder.newClient();
|
client = clientBuilder.build();
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
client.register(new LoggingFilter(new Slf4LoggingAdapter(logger), true));
|
client.register(new LoggingFilter(new Slf4LoggingAdapter(logger), true));
|
||||||
|
|
|
@ -21,6 +21,7 @@ import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.eclipse.jdt.annotation.NonNull;
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
@ -90,7 +91,7 @@ public class NeeoBrainService extends DefaultServletService {
|
||||||
private final ServiceContext context;
|
private final ServiceContext context;
|
||||||
|
|
||||||
/** The HTTP request */
|
/** The HTTP request */
|
||||||
private final HttpRequest request = new HttpRequest();
|
private final HttpRequest request;
|
||||||
|
|
||||||
/** The scheduler to use to schedule recipe execution */
|
/** The scheduler to use to schedule recipe execution */
|
||||||
private final ScheduledExecutorService scheduler = ThreadPoolManager
|
private final ScheduledExecutorService scheduler = ThreadPoolManager
|
||||||
|
@ -114,7 +115,7 @@ public class NeeoBrainService extends DefaultServletService {
|
||||||
* @param api the non-null api
|
* @param api the non-null api
|
||||||
* @param context the non-null context
|
* @param context the non-null context
|
||||||
*/
|
*/
|
||||||
public NeeoBrainService(NeeoApi api, ServiceContext context) {
|
public NeeoBrainService(NeeoApi api, ServiceContext context, ClientBuilder clientBuilder) {
|
||||||
Objects.requireNonNull(api, "api cannot be null");
|
Objects.requireNonNull(api, "api cannot be null");
|
||||||
Objects.requireNonNull(context, "context cannot be null");
|
Objects.requireNonNull(context, "context cannot be null");
|
||||||
|
|
||||||
|
@ -125,6 +126,7 @@ public class NeeoBrainService extends DefaultServletService {
|
||||||
scheduler.execute(() -> {
|
scheduler.execute(() -> {
|
||||||
resendState();
|
resendState();
|
||||||
});
|
});
|
||||||
|
request = new HttpRequest(clientBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue