From c5f87b44f34f118777f2721b45a57a1ba841a58a Mon Sep 17 00:00:00 2001 From: Wouter Born Date: Wed, 30 Sep 2020 03:53:43 +0200 Subject: [PATCH] [hueemulation] Replace Jersey dependency with JAX-RS Whiteboard (#8611) Fixes #7647 Signed-off-by: Wouter Born --- bundles/org.openhab.io.hueemulation/pom.xml | 4 - .../io/hueemulation/internal/ConfigStore.java | 3 +- .../internal/HueEmulationService.java | 117 +++++++++--------- .../internal/dto/HueAuthorizedConfig.java | 2 +- .../internal/dto/HueStateBulb.java | 4 +- .../internal/dto/HueStateColorBulb.java | 4 +- .../dto/changerequest/HueStateChange.java | 2 +- .../internal/rest/ConfigurationAccess.java | 38 +++--- .../internal/rest/LightsAndGroups.java | 98 +++++++-------- .../io/hueemulation/internal/rest/Rules.java | 49 ++++---- .../io/hueemulation/internal/rest/Scenes.java | 58 ++++----- .../hueemulation/internal/rest/Schedules.java | 51 ++++---- .../hueemulation/internal/rest/Sensors.java | 71 +++++------ .../internal/rest/StatusResource.java | 10 +- .../internal/rest/UserManagement.java | 43 ++++--- .../internal/upnp/UpnpServer.java | 15 +-- .../internal/rest/CommonSetup.java | 31 ++--- .../rest/ItemUIDtoHueIDMappingTests.java | 2 +- .../internal/rest/LightsAndGroupsTests.java | 2 +- .../internal/rest/RulesTests.java | 3 +- .../internal/rest/SceneTests.java | 2 +- .../internal/rest/ScheduleTests.java | 2 +- .../internal/rest/SensorTests.java | 2 +- .../internal/rest/UsersAndConfigTests.java | 2 +- .../mocks/ConfigStoreWithoutMetadata.java | 5 +- .../rest/mocks/DummyRuleRegistry.java | 5 +- .../hueemulation/internal/upnp/UpnpTests.java | 4 +- bundles/pom.xml | 3 +- features/openhab-addons/pom.xml | 1 - 29 files changed, 322 insertions(+), 311 deletions(-) diff --git a/bundles/org.openhab.io.hueemulation/pom.xml b/bundles/org.openhab.io.hueemulation/pom.xml index 1f50f23a6..0d1f77bda 100644 --- a/bundles/org.openhab.io.hueemulation/pom.xml +++ b/bundles/org.openhab.io.hueemulation/pom.xml @@ -14,10 +14,6 @@ openHAB Add-ons :: Bundles :: IO :: Hue Emulation Service - - org.glassfish.jersey.*;resolution:="optional" - - diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/ConfigStore.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/ConfigStore.java index a10e7f799..c084eb9d0 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/ConfigStore.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/ConfigStore.java @@ -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 { diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/HueEmulationService.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/HueEmulationService.java index 368428dea..17773a252 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/HueEmulationService.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/HueEmulationService.java @@ -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 getSingletons() { + return Set.of(userManagement, configurationAccess, lightItems, sensors, scenes, schedules, rules, + statusResource, accessInterceptor); + } + + Dictionary serviceProperties() { + Dictionary 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 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 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 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 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); + } } } } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueAuthorizedConfig.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueAuthorizedConfig.java index 2d25a16b1..b5dfa947c 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueAuthorizedConfig.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueAuthorizedConfig.java @@ -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 { diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateBulb.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateBulb.java index 81a81f7d0..5c1a28adf 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateBulb.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateBulb.java @@ -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() { diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateColorBulb.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateColorBulb.java index a908799da..68957c7d0 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateColorBulb.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/HueStateColorBulb.java @@ -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 diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/changerequest/HueStateChange.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/changerequest/HueStateChange.java index 6a4330a8e..899089b5b 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/changerequest/HueStateChange.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/dto/changerequest/HueStateChange.java @@ -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 diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/ConfigurationAccess.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/ConfigurationAccess.java index c815b4c0d..d1782c2e1 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/ConfigurationAccess.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/ConfigurationAccess.java @@ -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() { }.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"); } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroups.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroups.java index b321a175f..2e28f852d 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroups.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroups.java @@ -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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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"); } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Rules.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Rules.java index 67039626d..37ee39496 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Rules.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Rules.java @@ -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 { @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 { @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 { @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 { @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 { @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"); } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Scenes.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Scenes.java index 2f542ee85..16ae0d477 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Scenes.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Scenes.java @@ -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 { @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 { @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 { @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 { */ @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 { @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 { @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"); } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Schedules.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Schedules.java index 0c9ad30eb..801e55838 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Schedules.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Schedules.java @@ -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 { @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 { @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 { @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 { @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 { @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"); } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Sensors.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Sensors.java index c438fc650..f8fd1f001 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Sensors.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/Sensors.java @@ -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 { @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 { @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 { @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 { @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 { @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 { @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 { @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 { @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"); } diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/StatusResource.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/StatusResource.java index 4450a1dd6..c1891c55b 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/StatusResource.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/StatusResource.java @@ -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; diff --git a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/UserManagement.java b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/UserManagement.java index c2c3750bd..60e129aba 100644 --- a/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/UserManagement.java +++ b/bundles/org.openhab.io.hueemulation/src/main/java/org/openhab/io/hueemulation/internal/rest/UserManagement.java @@ -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 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(); } } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ItemUIDtoHueIDMappingTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ItemUIDtoHueIDMappingTests.java index cc41b1909..bfa5da42b 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ItemUIDtoHueIDMappingTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ItemUIDtoHueIDMappingTests.java @@ -62,7 +62,7 @@ public class ItemUIDtoHueIDMappingTests { } @AfterEach - public void tearDown() { + public void tearDown() throws Exception { commonSetup.dispose(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroupsTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroupsTests.java index c8a70e6a6..fc61d5369 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroupsTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/LightsAndGroupsTests.java @@ -83,7 +83,7 @@ public class LightsAndGroupsTests { } @AfterEach - public void tearDown() { + public void tearDown() throws Exception { commonSetup.dispose(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/RulesTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/RulesTests.java index 1dae91e74..0536831a0 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/RulesTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/RulesTests.java @@ -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(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SceneTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SceneTests.java index 68c223c46..17a949260 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SceneTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SceneTests.java @@ -99,7 +99,7 @@ public class SceneTests { } @AfterEach - public void tearDown() { + public void tearDown() throws Exception { commonSetup.dispose(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ScheduleTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ScheduleTests.java index bf809af33..869561303 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ScheduleTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/ScheduleTests.java @@ -99,7 +99,7 @@ public class ScheduleTests { } @AfterEach - public void tearDown() { + public void tearDown() throws Exception { RuleUtils.random = new Random(); commonSetup.dispose(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SensorTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SensorTests.java index 5c4a3b2c9..7ef24aa98 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SensorTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/SensorTests.java @@ -86,7 +86,7 @@ public class SensorTests { } @AfterEach - public void tearDown() { + public void tearDown() throws Exception { commonSetup.dispose(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/UsersAndConfigTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/UsersAndConfigTests.java index d8d711edd..f129e2109 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/UsersAndConfigTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/UsersAndConfigTests.java @@ -62,7 +62,7 @@ public class UsersAndConfigTests { } @AfterEach - public void tearDown() { + public void tearDown() throws Exception { commonSetup.dispose(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/ConfigStoreWithoutMetadata.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/ConfigStoreWithoutMetadata.java index e7d877cb4..6abc57f18 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/ConfigStoreWithoutMetadata.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/ConfigStoreWithoutMetadata.java @@ -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(); } diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/DummyRuleRegistry.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/DummyRuleRegistry.java index df2a893a4..0afee55b4 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/DummyRuleRegistry.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/rest/mocks/DummyRuleRegistry.java @@ -44,7 +44,6 @@ public class DummyRuleRegistry implements RuleRegistry { return items.values(); } - @NonNullByDefault({}) @Override public Stream stream() { return items.values().stream(); @@ -87,13 +86,11 @@ public class DummyRuleRegistry implements RuleRegistry { return put; } - @NonNullByDefault({}) @Override - public Collection getByTag(String tag) { + public Collection getByTag(@Nullable String tag) { return Collections.emptyList(); } - @NonNullByDefault({}) @Override public Collection getByTags(String... tags) { return Collections.emptyList(); diff --git a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/upnp/UpnpTests.java b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/upnp/UpnpTests.java index 2193f1f21..63da3f003 100644 --- a/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/upnp/UpnpTests.java +++ b/bundles/org.openhab.io.hueemulation/src/test/java/org/openhab/io/hueemulation/internal/upnp/UpnpTests.java @@ -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(); } diff --git a/bundles/pom.xml b/bundles/pom.xml index 440974cc5..84131e525 100644 --- a/bundles/pom.xml +++ b/bundles/pom.xml @@ -19,11 +19,12 @@ org.openhab.io.homekit + org.openhab.io.hueemulation org.openhab.io.imperihome + org.openhab.io.mqttembeddedbroker org.openhab.io.neeo org.openhab.io.openhabcloud org.openhab.io.transport.modbus - org.openhab.io.mqttembeddedbroker org.openhab.transform.bin2json org.openhab.transform.exec diff --git a/features/openhab-addons/pom.xml b/features/openhab-addons/pom.xml index bc6d0afd4..4f5e096bf 100644 --- a/features/openhab-addons/pom.xml +++ b/features/openhab-addons/pom.xml @@ -52,7 +52,6 @@ -