[hueemulation] Replace Jersey dependency with JAX-RS Whiteboard (#8611)
Fixes #7647 Signed-off-by: Wouter Born <github@maindrain.net>
This commit is contained in:
parent
d72a077ba9
commit
c5f87b44f3
@ -14,10 +14,6 @@
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: IO :: Hue Emulation Service</name>
|
||||
|
||||
<properties>
|
||||
<bnd.importpackage>org.glassfish.jersey.*;resolution:="optional"</bnd.importpackage>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.glassfish.grizzly/grizzly-http-server -->
|
||||
<dependency>
|
||||
|
||||
@ -71,8 +71,7 @@ import com.google.gson.GsonBuilder;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { ConfigStore.class }, configurationPid = {
|
||||
HueEmulationService.CONFIG_PID }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = ConfigStore.class, configurationPid = HueEmulationService.CONFIG_PID)
|
||||
@ConfigurableService(category = "io", label = "Hue Emulation", description_uri = "io:hueemulation")
|
||||
@NonNullByDefault
|
||||
public class ConfigStore {
|
||||
|
||||
@ -14,9 +14,8 @@ package org.openhab.io.hueemulation.internal;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.ws.rs.ApplicationPath;
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import javax.ws.rs.container.ContainerRequestContext;
|
||||
import javax.ws.rs.container.ContainerRequestFilter;
|
||||
@ -28,10 +27,6 @@ import javax.ws.rs.core.Application;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.ServerProperties;
|
||||
import org.glassfish.jersey.servlet.ServletContainer;
|
||||
import org.glassfish.jersey.servlet.ServletProperties;
|
||||
import org.openhab.io.hueemulation.internal.rest.ConfigurationAccess;
|
||||
import org.openhab.io.hueemulation.internal.rest.LightsAndGroups;
|
||||
import org.openhab.io.hueemulation.internal.rest.Rules;
|
||||
@ -42,6 +37,7 @@ import org.openhab.io.hueemulation.internal.rest.StatusResource;
|
||||
import org.openhab.io.hueemulation.internal.rest.UserManagement;
|
||||
import org.openhab.io.hueemulation.internal.upnp.UpnpServer;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
@ -54,8 +50,8 @@ import org.osgi.service.event.Event;
|
||||
import org.osgi.service.event.EventAdmin;
|
||||
import org.osgi.service.event.EventConstants;
|
||||
import org.osgi.service.event.EventHandler;
|
||||
import org.osgi.service.http.HttpService;
|
||||
import org.osgi.service.http.NamespaceException;
|
||||
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsName;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -75,17 +71,12 @@ import org.slf4j.LoggerFactory;
|
||||
* @author David Graeff - Initial Contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
@Component(immediate = true, service = { HueEmulationService.class }, property = {
|
||||
"com.eclipsesource.jaxrs.publish=false" })
|
||||
@Component(immediate = true, service = HueEmulationService.class)
|
||||
public class HueEmulationService implements EventHandler {
|
||||
|
||||
public static final String CONFIG_PID = "org.openhab.hueemulation";
|
||||
public static final String RESTAPI_PATH = "/api";
|
||||
|
||||
@ApplicationPath(RESTAPI_PATH)
|
||||
public static class JerseyApplication extends Application {
|
||||
|
||||
}
|
||||
public static final String REST_APP_NAME = "HueEmulation";
|
||||
|
||||
@PreMatching
|
||||
public class RequestInterceptor implements ContainerRequestFilter {
|
||||
@ -117,6 +108,34 @@ public class HueEmulationService implements EventHandler {
|
||||
}
|
||||
|
||||
private final ContainerRequestFilter requestCleaner = new RequestInterceptor();
|
||||
|
||||
/**
|
||||
* The Jax-RS application that starts up all REST activities.
|
||||
* It registers itself as a Jax-RS Whiteboard service and all Jax-RS resources that are targeting REST_APP_NAME will
|
||||
* start up.
|
||||
*/
|
||||
@JaxrsName(REST_APP_NAME)
|
||||
private class RESTapplication extends Application {
|
||||
private String root;
|
||||
|
||||
RESTapplication(String root) {
|
||||
this.root = root;
|
||||
}
|
||||
|
||||
@NonNullByDefault({})
|
||||
@Override
|
||||
public Set<Object> getSingletons() {
|
||||
return Set.of(userManagement, configurationAccess, lightItems, sensors, scenes, schedules, rules,
|
||||
statusResource, accessInterceptor);
|
||||
}
|
||||
|
||||
Dictionary<String, String> serviceProperties() {
|
||||
Dictionary<String, String> dict = new Hashtable<>();
|
||||
dict.put(JaxrsWhiteboardConstants.JAX_RS_APPLICATION_BASE, root);
|
||||
return dict;
|
||||
}
|
||||
}
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(HueEmulationService.class);
|
||||
private final LogAccessInterceptor accessInterceptor = new LogAccessInterceptor();
|
||||
|
||||
@ -144,9 +163,8 @@ public class HueEmulationService implements EventHandler {
|
||||
@Reference
|
||||
protected @NonNullByDefault({}) StatusResource statusResource;
|
||||
|
||||
@Reference
|
||||
protected @NonNullByDefault({}) HttpService httpService;
|
||||
private @NonNullByDefault({}) ServiceRegistration<?> eventHandler;
|
||||
private @Nullable ServiceRegistration<?> eventHandler;
|
||||
private @Nullable ServiceRegistration<Application> restService;
|
||||
|
||||
@Activate
|
||||
protected void activate(BundleContext bc) {
|
||||
@ -165,15 +183,11 @@ public class HueEmulationService implements EventHandler {
|
||||
|
||||
@Deactivate
|
||||
protected void deactivate() {
|
||||
try {
|
||||
if (eventHandler != null) {
|
||||
eventHandler.unregister();
|
||||
}
|
||||
} catch (IllegalStateException ignore) {
|
||||
}
|
||||
try {
|
||||
httpService.unregister(RESTAPI_PATH);
|
||||
} catch (IllegalArgumentException ignore) {
|
||||
unregisterEventHandler();
|
||||
|
||||
ServiceRegistration<Application> localRestService = restService;
|
||||
if (localRestService != null) {
|
||||
localRestService.unregister();
|
||||
}
|
||||
}
|
||||
|
||||
@ -185,39 +199,26 @@ public class HueEmulationService implements EventHandler {
|
||||
*/
|
||||
@Override
|
||||
public void handleEvent(@Nullable Event event) {
|
||||
try { // Only receive this event once
|
||||
eventHandler.unregister();
|
||||
eventHandler = null;
|
||||
} catch (IllegalStateException ignore) {
|
||||
}
|
||||
unregisterEventHandler();
|
||||
|
||||
ResourceConfig resourceConfig = ResourceConfig.forApplicationClass(JerseyApplication.class);
|
||||
resourceConfig.property(ServerProperties.APPLICATION_NAME, "HueEmulation");
|
||||
// don't look for implementations described by META-INF/services/*
|
||||
resourceConfig.property(ServerProperties.METAINF_SERVICES_LOOKUP_DISABLE, true);
|
||||
// disable auto discovery on server, as it's handled via OSGI
|
||||
resourceConfig.property(ServerProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true);
|
||||
|
||||
resourceConfig.property(ServerProperties.PROCESSING_RESPONSE_ERRORS_ENABLED, true);
|
||||
|
||||
resourceConfig.registerInstances(userManagement, configurationAccess, lightItems, sensors, scenes, schedules,
|
||||
rules, statusResource, accessInterceptor, requestCleaner);
|
||||
|
||||
try {
|
||||
Hashtable<String, String> initParams = new Hashtable<>();
|
||||
initParams.put("com.sun.jersey.api.json.POJOMappingFeature", "false");
|
||||
initParams.put(ServletProperties.PROVIDER_WEB_APP, "false");
|
||||
httpService.registerServlet(RESTAPI_PATH, new ServletContainer(resourceConfig), initParams, null);
|
||||
UpnpServer localDiscovery = discovery;
|
||||
if (localDiscovery == null) {
|
||||
logger.warn("The UPnP Server service has not been started!");
|
||||
} else if (!localDiscovery.upnpAnnouncementThreadRunning()) {
|
||||
localDiscovery.handleEvent(null);
|
||||
}
|
||||
statusResource.startUpnpSelfTest();
|
||||
ServiceRegistration<Application> localRestService = restService;
|
||||
if (localRestService == null) {
|
||||
RESTapplication app = new RESTapplication(RESTAPI_PATH);
|
||||
BundleContext context = FrameworkUtil.getBundle(getClass()).getBundleContext();
|
||||
restService = context.registerService(Application.class, app, app.serviceProperties());
|
||||
logger.info("Hue Emulation service available under {}", RESTAPI_PATH);
|
||||
} catch (ServletException | NamespaceException e) {
|
||||
logger.warn("Could not start Hue Emulation service: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void unregisterEventHandler() {
|
||||
ServiceRegistration<?> localEventHandler = eventHandler;
|
||||
if (localEventHandler != null) {
|
||||
try {
|
||||
localEventHandler.unregister();
|
||||
eventHandler = null;
|
||||
} catch (IllegalStateException e) {
|
||||
logger.debug("EventHandler already unregistered", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ public class HueAuthorizedConfig extends HueUnauthorizedConfig {
|
||||
|
||||
/**
|
||||
* Return a json serializer that behaves like the default one, but updates the UTC and localtime fields
|
||||
* before each serializion.
|
||||
* before each serialization.
|
||||
*/
|
||||
@NonNullByDefault({})
|
||||
public static class Serializer implements JsonSerializer<HueAuthorizedConfig> {
|
||||
|
||||
@ -24,11 +24,11 @@ import org.openhab.core.library.types.PercentType;
|
||||
public class HueStateBulb extends HueStatePlug {
|
||||
// https://github.com/openhab/openhab-addons/issues/2881
|
||||
// Apparently the maximum brightness is 254
|
||||
public static int MAX_BRI = 254;
|
||||
public static final int MAX_BRI = 254;
|
||||
public int bri = 0;
|
||||
|
||||
/** white color temperature, 154 (cold) - 500 (warm) */
|
||||
public static int MAX_CT = 500;
|
||||
public static final int MAX_CT = 500;
|
||||
public int ct = 500;
|
||||
|
||||
protected HueStateBulb() {
|
||||
|
||||
@ -25,9 +25,9 @@ import org.openhab.core.library.types.PercentType;
|
||||
*
|
||||
*/
|
||||
public class HueStateColorBulb extends HueStateBulb {
|
||||
public static int MAX_HUE = 65535; // For extended color light bulbs
|
||||
public static final int MAX_HUE = 65535; // For extended color light bulbs
|
||||
public int hue = 0;
|
||||
public static int MAX_SAT = 254;
|
||||
public static final int MAX_SAT = 254;
|
||||
public int sat = 0;
|
||||
|
||||
// color as array of xy-coordinates
|
||||
|
||||
@ -15,7 +15,7 @@ package org.openhab.io.hueemulation.internal.dto.changerequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A POST message on a light entpoint will contain this change message body.
|
||||
* A POST message on a light endpoint will contain this change message body.
|
||||
* Not all fields will be set and always need to be checked.
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
|
||||
@ -27,6 +27,7 @@ import javax.ws.rs.core.UriInfo;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueUnauthorizedConfig;
|
||||
import org.openhab.io.hueemulation.internal.dto.changerequest.HueChangeRequest;
|
||||
@ -35,19 +36,22 @@ import org.openhab.io.hueemulation.internal.dto.response.HueResponse.HueErrorMes
|
||||
import org.osgi.service.cm.ConfigurationAdmin;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = {
|
||||
ConfigurationAccess.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = ConfigurationAccess.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -62,8 +66,8 @@ public class ConfigurationAccess {
|
||||
@GET
|
||||
@Path("config")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return the reduced configuration")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return the reduced configuration", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getReducedConfigApi() {
|
||||
return Response.ok(cs.gson.toJson(cs.ds.config, new TypeToken<HueUnauthorizedConfig>() {
|
||||
}.getType())).build();
|
||||
@ -72,10 +76,10 @@ public class ConfigurationAccess {
|
||||
@GET
|
||||
@Path("{username}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return the full data store")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return the full data store", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getAllApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -85,10 +89,10 @@ public class ConfigurationAccess {
|
||||
@GET
|
||||
@Path("{username}/config")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return the configuration")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return the configuration", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getFullConfigApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -98,10 +102,10 @@ public class ConfigurationAccess {
|
||||
@PUT
|
||||
@Path("{username}/config")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return the reduced configuration")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return the reduced configuration", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response putFullConfigApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -43,6 +43,7 @@ import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.DeviceType;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.StateUtils;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueGroupEntry;
|
||||
@ -57,15 +58,17 @@ 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.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* Listens to the ItemRegistry for items that fulfill one of these criteria:
|
||||
@ -93,7 +96,9 @@ import io.swagger.annotations.ApiResponses;
|
||||
* @author David Graeff - Initial contribution
|
||||
* @author Florian Schmidt - Removed base type restriction from Group items
|
||||
*/
|
||||
@Component(immediate = false, service = { LightsAndGroups.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = LightsAndGroups.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -241,10 +246,9 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/lights")
|
||||
@ApiOperation(value = "Return all lights")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all lights", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getAllLightsApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -253,10 +257,10 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/lights/new")
|
||||
@ApiOperation(value = "Return new lights since last scan. Returns an empty list for openHAB as we do not cache that information.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return new lights since last scan. Returns an empty list for openHAB as we do not cache that information.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getNewLights(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -265,10 +269,10 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
|
||||
@POST
|
||||
@Path("{username}/lights")
|
||||
@ApiOperation(value = "Starts a new scan for compatible items. This is usually not necessary, because we are observing the item registry.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Starts a new scan for compatible items. This is usually not necessary, because we are observing the item registry.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response postNewLights(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -277,11 +281,10 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/lights/{id}")
|
||||
@ApiOperation(value = "Return a light")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a light", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getLightApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "light id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "light id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -291,12 +294,12 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@DELETE
|
||||
@Path("{username}/lights/{id}")
|
||||
@ApiOperation(value = "Deletes the item that is represented by this id")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The item got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes the item that is represented by this id", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The item got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeLightAPI(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -316,11 +319,10 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@PUT
|
||||
@Path("{username}/lights/{id}")
|
||||
@ApiOperation(value = "Rename a light")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Rename a light", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response renameLightApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "light id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "light id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -345,11 +347,10 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@PUT
|
||||
@Path("{username}/lights/{id}/state")
|
||||
@ApiOperation(value = "Set light state")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Set light state", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response setLightStateApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "light id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "light id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -391,11 +392,11 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@PUT
|
||||
@Path("{username}/groups/{id}/action")
|
||||
@ApiOperation(value = "Initiate group action")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Initiate group action", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response setGroupActionApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "group id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "group id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -436,10 +437,9 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/groups")
|
||||
@ApiOperation(value = "Return all groups")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all groups", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getAllGroupsApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -448,11 +448,10 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/groups/{id}")
|
||||
@ApiOperation(value = "Return a group")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a group", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getGroupApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "group id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "group id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -462,10 +461,9 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@POST
|
||||
@Path("{username}/groups")
|
||||
@ApiOperation(value = "Create a new group")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Create a new group", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response postNewGroup(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -506,12 +504,12 @@ public class LightsAndGroups implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@DELETE
|
||||
@Path("{username}/groups/{id}")
|
||||
@ApiOperation(value = "Deletes the item that is represented by this id")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The item got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes the item that is represented by this id", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The item got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeGroupAPI(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@ import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.RuleUtils;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueRuleEntry;
|
||||
@ -59,18 +60,22 @@ 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.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* Handles Hue rules via the automation subsystem and the corresponding REST interface
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { Rules.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = Rules.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -234,10 +239,9 @@ public class Rules implements RegistryChangeListener<Rule> {
|
||||
@GET
|
||||
@Path("{username}/rules")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return all rules")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all rules", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getRulesApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -246,11 +250,10 @@ public class Rules implements RegistryChangeListener<Rule> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/rules/{id}")
|
||||
@ApiOperation(value = "Return a rule")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a rule", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getRuleApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "rule id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "rule id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -259,12 +262,12 @@ public class Rules implements RegistryChangeListener<Rule> {
|
||||
|
||||
@DELETE
|
||||
@Path("{username}/rules/{id}")
|
||||
@ApiOperation(value = "Deletes a rule")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The user got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes a rule", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The user got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeRuleApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "Rule to remove") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "Rule to remove") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -279,11 +282,10 @@ public class Rules implements RegistryChangeListener<Rule> {
|
||||
|
||||
@PUT
|
||||
@Path("{username}/rules/{id}")
|
||||
@ApiOperation(value = "Set rule attributes")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Set rule attributes", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response modifyRuleApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "rule id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "rule id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -334,10 +336,9 @@ public class Rules implements RegistryChangeListener<Rule> {
|
||||
@SuppressWarnings({ "null" })
|
||||
@POST
|
||||
@Path("{username}/rules")
|
||||
@ApiOperation(value = "Create a new rule")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Create a new rule", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response postNewRule(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -49,6 +49,7 @@ import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.StateUtils;
|
||||
import org.openhab.io.hueemulation.internal.automation.dto.ItemCommandActionConfig;
|
||||
@ -63,20 +64,24 @@ 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.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* Handles Hue scenes via the automation subsystem and the corresponding REST interface
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { Scenes.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = Scenes.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -165,10 +170,9 @@ public class Scenes implements RegistryChangeListener<Rule> {
|
||||
@GET
|
||||
@Path("{username}/scenes")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return all scenes")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all scenes", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getScenesApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -178,11 +182,10 @@ public class Scenes implements RegistryChangeListener<Rule> {
|
||||
@SuppressWarnings({ "unused", "null" })
|
||||
@GET
|
||||
@Path("{username}/scenes/{id}")
|
||||
@ApiOperation(value = "Return a scene")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a scene", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getSceneApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "scene id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "scene id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -208,12 +211,12 @@ public class Scenes implements RegistryChangeListener<Rule> {
|
||||
|
||||
@DELETE
|
||||
@Path("{username}/scenes/{id}")
|
||||
@ApiOperation(value = "Deletes a scene")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The user got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes a scene", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The user got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeSceneApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "Scene to remove") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "Scene to remove") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -248,11 +251,10 @@ public class Scenes implements RegistryChangeListener<Rule> {
|
||||
*/
|
||||
@PUT
|
||||
@Path("{username}/scenes/{id}")
|
||||
@ApiOperation(value = "Set scene attributes")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Set scene attributes", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response modifySceneApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "scene id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "scene id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -317,10 +319,9 @@ public class Scenes implements RegistryChangeListener<Rule> {
|
||||
@SuppressWarnings({ "null" })
|
||||
@POST
|
||||
@Path("{username}/scenes")
|
||||
@ApiOperation(value = "Create a new scene")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Create a new scene", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response postNewScene(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -372,12 +373,11 @@ public class Scenes implements RegistryChangeListener<Rule> {
|
||||
|
||||
@PUT
|
||||
@Path("{username}/scenes/{id}/lightstates/{lightid}")
|
||||
@ApiOperation(value = "Set scene attributes")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Set scene attributes", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response modifySceneLightStateApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "scene id") String id,
|
||||
@PathParam("lightid") @ApiParam(value = "light id") String lightid, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "scene id") String id,
|
||||
@PathParam("lightid") @Parameter(description = "light id") String lightid, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ import org.openhab.core.automation.util.RuleBuilder;
|
||||
import org.openhab.core.common.registry.RegistryChangeListener;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.RuleUtils;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueDataStore;
|
||||
@ -56,13 +57,15 @@ 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.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* Enables the schedule part of the Hue REST API. Uses automation rules with GenericCronTrigger, TimerTrigger and
|
||||
@ -74,7 +77,9 @@ import io.swagger.annotations.ApiResponses;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { Schedules.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = Schedules.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -228,10 +233,9 @@ public class Schedules implements RegistryChangeListener<Rule> {
|
||||
@GET
|
||||
@Path("{username}/schedules")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ApiOperation(value = "Return all schedules")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all schedules", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getSchedulesApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -240,11 +244,10 @@ public class Schedules implements RegistryChangeListener<Rule> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/schedules/{id}")
|
||||
@ApiOperation(value = "Return a schedule")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a schedule", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getScheduleApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "schedule id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "schedule id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -253,12 +256,12 @@ public class Schedules implements RegistryChangeListener<Rule> {
|
||||
|
||||
@DELETE
|
||||
@Path("{username}/schedules/{id}")
|
||||
@ApiOperation(value = "Deletes a schedule")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The user got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes a schedule", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The user got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeScheduleApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "Schedule to remove") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "Schedule to remove") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -273,11 +276,11 @@ public class Schedules implements RegistryChangeListener<Rule> {
|
||||
|
||||
@PUT
|
||||
@Path("{username}/schedules/{id}")
|
||||
@ApiOperation(value = "Set schedule attributes")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Set schedule attributes", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response modifyScheduleApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "schedule id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "schedule id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -311,10 +314,10 @@ public class Schedules implements RegistryChangeListener<Rule> {
|
||||
@SuppressWarnings({ "null" })
|
||||
@POST
|
||||
@Path("{username}/schedules")
|
||||
@ApiOperation(value = "Create a new schedule")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Create a new schedule", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response postNewSchedule(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import org.openhab.core.items.Item;
|
||||
import org.openhab.core.items.ItemRegistry;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueNewLights;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueSensorEntry;
|
||||
@ -45,13 +46,15 @@ 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.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* Listens to the ItemRegistry and add all DecimalType, OnOffType, ContactType, DimmerType items
|
||||
@ -59,7 +62,9 @@ import io.swagger.annotations.ApiResponses;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { Sensors.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = Sensors.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -144,10 +149,9 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/sensors")
|
||||
@ApiOperation(value = "Return all sensors")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all sensors", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getAllSensorsApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -156,10 +160,10 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/sensors/new")
|
||||
@ApiOperation(value = "Return new sensors since last scan. Returns an empty list for openHAB as we do not cache that information.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return new sensors since last scan. Returns an empty list for openHAB as we do not cache that information.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getNewSensors(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -168,10 +172,10 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
|
||||
@POST
|
||||
@Path("{username}/sensors")
|
||||
@ApiOperation(value = "Starts a new scan for compatible items. This is usually not necessary, because we are observing the item registry.")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Starts a new scan for compatible items. This is usually not necessary, because we are observing the item registry.", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response postNewLights(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -180,11 +184,10 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
|
||||
@GET
|
||||
@Path("{username}/sensors/{id}")
|
||||
@ApiOperation(value = "Return a sensor")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a sensor", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getSensorApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "sensor id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "sensor id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -194,11 +197,11 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@GET
|
||||
@Path("{username}/sensors/{id}/config")
|
||||
@ApiOperation(value = "Return a sensor config. Always empty")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a sensor config. Always empty", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getSensorConfigApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "sensor id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "sensor id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -214,12 +217,12 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@DELETE
|
||||
@Path("{username}/sensors/{id}")
|
||||
@ApiOperation(value = "Deletes the sensor that is represented by this id")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The item got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes the sensor that is represented by this id", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The item got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeSensorAPI(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "id") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "id") String id) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -239,11 +242,10 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
@SuppressWarnings({ "null", "unused" })
|
||||
@PUT
|
||||
@Path("{username}/sensors/{id}")
|
||||
@ApiOperation(value = "Rename a sensor")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Rename a sensor", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response renameLightApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "light id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "light id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -267,11 +269,10 @@ public class Sensors implements RegistryChangeListener<Item> {
|
||||
|
||||
@PUT
|
||||
@Path("{username}/sensors/{id}/state")
|
||||
@ApiOperation(value = "Set sensor state")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Set sensor state", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response setSensorStateApi(@Context UriInfo uri, //
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "sensor id") String id, String body) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "sensor id") String id, String body) {
|
||||
if (!userManagement.authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -33,11 +33,15 @@ import org.jupnp.model.meta.RemoteDevice;
|
||||
import org.jupnp.registry.Registry;
|
||||
import org.jupnp.registry.RegistryListener;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.upnp.UpnpServer;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||
import org.osgi.service.component.annotations.ReferencePolicyOption;
|
||||
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -49,9 +53,11 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { StatusResource.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Path("")
|
||||
@Component(immediate = false, service = StatusResource.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
public class StatusResource implements RegistryListener {
|
||||
@Reference(cardinality = ReferenceCardinality.OPTIONAL, policyOption = ReferencePolicyOption.GREEDY)
|
||||
protected @Nullable UpnpServer discovery;
|
||||
|
||||
@ -33,6 +33,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.common.registry.DefaultAbstractManagedProvider;
|
||||
import org.openhab.core.storage.StorageService;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.openhab.io.hueemulation.internal.HueEmulationService;
|
||||
import org.openhab.io.hueemulation.internal.NetworkUtils;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueUserAuth;
|
||||
import org.openhab.io.hueemulation.internal.dto.HueUserAuthWithSecrets;
|
||||
@ -42,15 +43,17 @@ import org.openhab.io.hueemulation.internal.dto.response.HueSuccessResponseCreat
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsApplicationSelect;
|
||||
import org.osgi.service.jaxrs.whiteboard.propertytypes.JaxrsResource;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import io.swagger.annotations.ApiResponse;
|
||||
import io.swagger.annotations.ApiResponses;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
|
||||
/**
|
||||
* Manages users of this emulated HUE bridge. Stores users in the frameworks storage backend.
|
||||
@ -64,7 +67,9 @@ import io.swagger.annotations.ApiResponses;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@Component(immediate = false, service = { UserManagement.class }, property = "com.eclipsesource.jaxrs.publish=false")
|
||||
@Component(immediate = false, service = UserManagement.class)
|
||||
@JaxrsResource
|
||||
@JaxrsApplicationSelect("(" + JaxrsWhiteboardConstants.JAX_RS_NAME + "=" + HueEmulationService.REST_APP_NAME + ")")
|
||||
@NonNullByDefault
|
||||
@Path("")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@ -147,9 +152,9 @@ public class UserManagement extends DefaultAbstractManagedProvider<HueUserAuthWi
|
||||
}
|
||||
|
||||
@POST
|
||||
@ApiOperation(value = "Create an API Key")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "API Key created"),
|
||||
@ApiResponse(code = 403, message = "Link button not pressed") })
|
||||
@Operation(summary = "Create an API Key", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "API Key created"),
|
||||
@ApiResponse(responseCode = "403", description = "Link button not pressed") })
|
||||
public Response createNewUser(@Context UriInfo uri, String body) {
|
||||
if (!cs.ds.config.linkbutton) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.LINK_BUTTON_NOT_PRESSED,
|
||||
@ -175,11 +180,10 @@ public class UserManagement extends DefaultAbstractManagedProvider<HueUserAuthWi
|
||||
|
||||
@GET
|
||||
@Path("{username}/config/whitelist/{userid}")
|
||||
@ApiOperation(value = "Return a user")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return a user", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getUserApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("userid") @ApiParam(value = "User ID") String userid) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("userid") @Parameter(description = "User ID") String userid) {
|
||||
if (!authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -188,10 +192,9 @@ public class UserManagement extends DefaultAbstractManagedProvider<HueUserAuthWi
|
||||
|
||||
@GET
|
||||
@Path("{username}/config/whitelist")
|
||||
@ApiOperation(value = "Return all users")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "OK") })
|
||||
@Operation(summary = "Return all users", responses = { @ApiResponse(responseCode = "200", description = "OK") })
|
||||
public Response getAllUsersApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username) {
|
||||
@PathParam("username") @Parameter(description = "username") String username) {
|
||||
if (!authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
@ -200,12 +203,12 @@ public class UserManagement extends DefaultAbstractManagedProvider<HueUserAuthWi
|
||||
|
||||
@DELETE
|
||||
@Path("{username}/config/whitelist/{id}")
|
||||
@ApiOperation(value = "Deletes a user")
|
||||
@ApiResponses(value = { @ApiResponse(code = 200, message = "The user got removed"),
|
||||
@ApiResponse(code = 403, message = "Access denied") })
|
||||
@Operation(summary = "Deletes a user", responses = {
|
||||
@ApiResponse(responseCode = "200", description = "The user got removed"),
|
||||
@ApiResponse(responseCode = "403", description = "Access denied") })
|
||||
public Response removeUserApi(@Context UriInfo uri,
|
||||
@PathParam("username") @ApiParam(value = "username") String username,
|
||||
@PathParam("id") @ApiParam(value = "User to remove") String id) {
|
||||
@PathParam("username") @Parameter(description = "username") String username,
|
||||
@PathParam("id") @Parameter(description = "User to remove") String id) {
|
||||
if (!authorizeUser(username)) {
|
||||
return NetworkUtils.singleError(cs.gson, uri, HueResponse.UNAUTHORIZED, "Not Authorized");
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -55,8 +56,6 @@ import javax.ws.rs.core.Response;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.glassfish.jersey.client.ClientConfig;
|
||||
import org.glassfish.jersey.client.ClientProperties;
|
||||
import org.openhab.io.hueemulation.internal.ConfigStore;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
@ -82,8 +81,7 @@ import org.slf4j.LoggerFactory;
|
||||
@NonNullByDefault
|
||||
@Component(immediate = false, // Don't start the upnp server on its own. Must be pulled in by HueEmulationService.
|
||||
configurationPolicy = ConfigurationPolicy.IGNORE, property = {
|
||||
EventConstants.EVENT_TOPIC + "=" + ConfigStore.EVENT_ADDRESS_CHANGED,
|
||||
"com.eclipsesource.jaxrs.publish=false" }, //
|
||||
EventConstants.EVENT_TOPIC + "=" + ConfigStore.EVENT_ADDRESS_CHANGED }, //
|
||||
service = { UpnpServer.class, EventHandler.class })
|
||||
public class UpnpServer extends HttpServlet implements Consumer<HueEmulationConfigWithRuntime>, EventHandler {
|
||||
/**
|
||||
@ -121,6 +119,9 @@ public class UpnpServer extends HttpServlet implements Consumer<HueEmulationConf
|
||||
@Reference
|
||||
protected @NonNullByDefault({}) HttpService httpService;
|
||||
|
||||
@Reference
|
||||
protected @NonNullByDefault({}) ClientBuilder clientBuilder;
|
||||
|
||||
public boolean overwriteReadyToFalse = false;
|
||||
|
||||
private HueEmulationConfigWithRuntime config;
|
||||
@ -242,11 +243,7 @@ public class UpnpServer extends HttpServlet implements Consumer<HueEmulationConf
|
||||
}
|
||||
|
||||
selfTests.clear();
|
||||
|
||||
ClientConfig configuration = new ClientConfig();
|
||||
configuration = configuration.property(ClientProperties.CONNECT_TIMEOUT, 1000);
|
||||
configuration = configuration.property(ClientProperties.READ_TIMEOUT, 1000);
|
||||
Client client = ClientBuilder.newClient(configuration);
|
||||
Client client = clientBuilder.connectTimeout(1, TimeUnit.SECONDS).readTimeout(1, TimeUnit.SECONDS).build();
|
||||
Response response;
|
||||
String url = "";
|
||||
try {
|
||||
|
||||
@ -34,12 +34,9 @@ import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
|
||||
import org.glassfish.jersey.logging.LoggingFeature;
|
||||
import org.glassfish.jersey.logging.LoggingFeature.Verbosity;
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
import org.openhab.core.events.EventPublisher;
|
||||
import org.openhab.core.items.MetadataRegistry;
|
||||
import org.openhab.core.net.NetworkAddressService;
|
||||
@ -61,15 +58,19 @@ import org.osgi.service.cm.ConfigurationAdmin;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.WARN)
|
||||
public class CommonSetup {
|
||||
|
||||
public UserManagement userManagement;
|
||||
|
||||
public @Mock EventPublisher eventPublisher;
|
||||
|
||||
public String basePath;
|
||||
public Client client;
|
||||
public ConfigStore cs;
|
||||
public HttpServer server;
|
||||
|
||||
UserManagement userManagement;
|
||||
|
||||
AutoCloseable mocksCloseable;
|
||||
|
||||
@Mock
|
||||
EventPublisher eventPublisher;
|
||||
|
||||
@Mock
|
||||
ConfigurationAdmin configAdmin;
|
||||
@ -101,11 +102,9 @@ public class CommonSetup {
|
||||
}
|
||||
};
|
||||
|
||||
public Client client;
|
||||
public HttpServer server;
|
||||
public String basePath;
|
||||
|
||||
public CommonSetup(boolean withMetadata) throws IOException {
|
||||
mocksCloseable = MockitoAnnotations.openMocks(this);
|
||||
|
||||
when(configAdmin.getConfiguration(anyString())).thenReturn(configAdminConfig);
|
||||
when(configAdmin.getConfiguration(anyString(), any())).thenReturn(configAdminConfig);
|
||||
Dictionary<String, Object> mockProperties = new Hashtable<>();
|
||||
@ -154,12 +153,14 @@ public class CommonSetup {
|
||||
client = ClientBuilder.newClient();
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
public void dispose() throws Exception {
|
||||
if (client != null) {
|
||||
client.close();
|
||||
}
|
||||
if (server != null) {
|
||||
server.shutdownNow();
|
||||
}
|
||||
|
||||
mocksCloseable.close();
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,7 +62,7 @@ public class ItemUIDtoHueIDMappingTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ public class LightsAndGroupsTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -61,6 +61,7 @@ import com.google.gson.reflect.TypeToken;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RulesTests {
|
||||
|
||||
protected @NonNullByDefault({}) CommonSetup commonSetup;
|
||||
protected @NonNullByDefault({}) ConfigStore cs;
|
||||
protected @NonNullByDefault({}) ItemRegistry itemRegistry;
|
||||
@ -106,7 +107,7 @@ public class RulesTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
RuleUtils.random = new Random();
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ public class SceneTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -99,7 +99,7 @@ public class ScheduleTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
RuleUtils.random = new Random();
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
@ -86,7 +86,7 @@ public class SensorTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -62,7 +62,7 @@ public class UsersAndConfigTests {
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void tearDown() {
|
||||
public void tearDown() throws Exception {
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@ package org.openhab.io.hueemulation.internal.rest.mocks;
|
||||
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNull;
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.items.Item;
|
||||
import org.openhab.core.net.NetworkAddressService;
|
||||
@ -27,6 +27,7 @@ import org.osgi.service.cm.ConfigurationAdmin;
|
||||
*
|
||||
* @author David Graeff - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class ConfigStoreWithoutMetadata extends ConfigStore {
|
||||
|
||||
public ConfigStoreWithoutMetadata(NetworkAddressService networkAddressService, ConfigurationAdmin configAdmin,
|
||||
@ -39,7 +40,7 @@ public class ConfigStoreWithoutMetadata extends ConfigStore {
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull String mapItemUIDtoHueID(@Nullable Item item) {
|
||||
public String mapItemUIDtoHueID(@Nullable Item item) {
|
||||
if (item == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@ -44,7 +44,6 @@ public class DummyRuleRegistry implements RuleRegistry {
|
||||
return items.values();
|
||||
}
|
||||
|
||||
@NonNullByDefault({})
|
||||
@Override
|
||||
public Stream<Rule> stream() {
|
||||
return items.values().stream();
|
||||
@ -87,13 +86,11 @@ public class DummyRuleRegistry implements RuleRegistry {
|
||||
return put;
|
||||
}
|
||||
|
||||
@NonNullByDefault({})
|
||||
@Override
|
||||
public Collection<Rule> getByTag(String tag) {
|
||||
public Collection<Rule> getByTag(@Nullable String tag) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNullByDefault({})
|
||||
@Override
|
||||
public Collection<Rule> getByTags(String... tags) {
|
||||
return Collections.emptyList();
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.ws.rs.client.ClientBuilder;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.glassfish.grizzly.osgi.httpservice.HttpServiceImpl;
|
||||
@ -81,6 +82,7 @@ public class UpnpTests {
|
||||
return null;
|
||||
}).when(executor).execute(ArgumentMatchers.any());
|
||||
subject = new UpnpServer(executor);
|
||||
subject.clientBuilder = ClientBuilder.newBuilder();
|
||||
subject.httpService = httpServiceImpl;
|
||||
subject.cs = commonSetup.cs;
|
||||
subject.overwriteReadyToFalse = true;
|
||||
@ -94,7 +96,7 @@ public class UpnpTests {
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
public static void tearDownHttp() {
|
||||
public static void tearDownHttp() throws Exception {
|
||||
mainHttpHandler.unregisterAll();
|
||||
commonSetup.dispose();
|
||||
}
|
||||
|
||||
@ -19,11 +19,12 @@
|
||||
<modules>
|
||||
<!-- io -->
|
||||
<module>org.openhab.io.homekit</module>
|
||||
<module>org.openhab.io.hueemulation</module>
|
||||
<module>org.openhab.io.imperihome</module>
|
||||
<module>org.openhab.io.mqttembeddedbroker</module>
|
||||
<module>org.openhab.io.neeo</module>
|
||||
<module>org.openhab.io.openhabcloud</module>
|
||||
<module>org.openhab.io.transport.modbus</module>
|
||||
<module>org.openhab.io.mqttembeddedbroker</module>
|
||||
<!-- transformations -->
|
||||
<module>org.openhab.transform.bin2json</module>
|
||||
<module>org.openhab.transform.exec</module>
|
||||
|
||||
@ -52,7 +52,6 @@
|
||||
|
||||
<!-- temporarily exclude add-ons, which are still excluded from the build -->
|
||||
<exclude name="**/org.openhab.binding.netatmo/**/feature.xml"/>
|
||||
<exclude name="**/org.openhab.io.hueemulation/**/feature.xml"/>
|
||||
</fileset>
|
||||
<filterchain>
|
||||
<linecontainsRegExp>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user