diff --git a/kura/org.eclipse.kura.rest.network.configuration.provider/src/main/java/org/eclipse/kura/internal/rest/network/configuration/NetworkConfigurationRestService.java b/kura/org.eclipse.kura.rest.network.configuration.provider/src/main/java/org/eclipse/kura/internal/rest/network/configuration/NetworkConfigurationRestService.java index f099e429430..2bd0ebfa7ef 100644 --- a/kura/org.eclipse.kura.rest.network.configuration.provider/src/main/java/org/eclipse/kura/internal/rest/network/configuration/NetworkConfigurationRestService.java +++ b/kura/org.eclipse.kura.rest.network.configuration.provider/src/main/java/org/eclipse/kura/internal/rest/network/configuration/NetworkConfigurationRestService.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -23,6 +24,7 @@ import javax.annotation.security.RolesAllowed; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -31,13 +33,18 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import org.eclipse.kura.KuraErrorCode; +import org.eclipse.kura.KuraException; import org.eclipse.kura.configuration.ComponentConfiguration; import org.eclipse.kura.configuration.ConfigurationService; import org.eclipse.kura.crypto.CryptoService; import org.eclipse.kura.request.handler.jaxrs.DefaultExceptionHandler; import org.eclipse.kura.rest.configuration.api.ComponentConfigurationDTO; import org.eclipse.kura.rest.configuration.api.ComponentConfigurationList; +import org.eclipse.kura.rest.configuration.api.CreateFactoryComponentConfigurationsRequest; import org.eclipse.kura.rest.configuration.api.DTOUtil; +import org.eclipse.kura.rest.configuration.api.DeleteFactoryComponentRequest; +import org.eclipse.kura.rest.configuration.api.FactoryComponentConfigurationDTO; import org.eclipse.kura.rest.configuration.api.FailureHandler; import org.eclipse.kura.rest.configuration.api.PidSet; import org.eclipse.kura.rest.configuration.api.UpdateComponentConfigurationRequest; @@ -71,15 +78,6 @@ public void setCryptoService(CryptoService cryptoService) { this.cryptoService = cryptoService; } - /** - * GET method. - * - * Lists the tracked network configurable component Pids - * - * @return a List of String objects representing the Pids of network factory components - * tracked by the - * {@link ConfigurationService} - */ @GET @RolesAllowed("network.configuration") @Path("/configurableComponents") @@ -91,17 +89,6 @@ public PidSet listNetworkConfigurableComponentsPids() { return new PidSet(pids); } - /** - * GET method. - * - * Lists all the network component configurations of all the ConfigurableComponents - * tracked by the - * {@link ConfigurationService} - * - * @return a list of {@link ComponentConfigurationDTO} that map all the - * configuration parameters tracked for the - * network configurable components tracked. - */ @GET @RolesAllowed("network.configuration") @Path("/configurableComponents/configurations") @@ -110,7 +97,10 @@ public ComponentConfigurationList listNetworkConfiguration() { final List ccs = new ArrayList<>(); try { for (String config : NETWORK_CONFIGURATION_PIDS) { - ccs.add(this.configurationService.getComponentConfiguration(config)); + ComponentConfiguration configuration = this.configurationService.getComponentConfiguration(config); + if (null != configuration) { + ccs.add(configuration); + } } } catch (final Exception e) { throw DefaultExceptionHandler.toWebApplicationException(e); @@ -118,18 +108,6 @@ public ComponentConfigurationList listNetworkConfiguration() { return DTOUtil.toComponentConfigurationList(ccs, this.cryptoService, false).replacePasswordsWithPlaceholder(); } - /** - * POST method. - * - * Lists the network component configurations of all the network ConfigurableComponents tracked - * by the - * {@link ConfigurationService} that match the filter specified - * - * @param filter - * A String representing an OSGi filter - * @return a list of {@link ComponentConfigurationDTO}s for the components that - * match the specified filter - */ @POST @RolesAllowed("network.configuration") @Path("/configurableComponents/configurations/byPid") @@ -152,16 +130,6 @@ public ComponentConfigurationList listNetworkComponentConfigurations(final PidSe .replacePasswordsWithPlaceholder(); } - /** - * POST method. - * - * This method provides the default network Component Configuration for the component identified by - * the specified PID in the body request - * - * @param componentPid - * @return The default {@link ComponentConfiguration} or a null object if the - * component is not tracked - */ @POST @RolesAllowed("network.configuration") @Path("/configurableComponents/configurations/byPid/_default") @@ -188,13 +156,6 @@ public ComponentConfigurationList listDefaultNetworkComponentConfiguration(final return new ComponentConfigurationList(requestResult); } - /** - * POST method. - * - * This method let the user update the configuration of multiple network configurable components - * - * @param request - */ @PUT @RolesAllowed("network.configuration") @Path("/configurableComponents/configurations/_update") @@ -220,6 +181,89 @@ public Response updateNetworkComponentConfigurations(UpdateComponentConfiguratio return Response.ok().build(); } + @GET + @RolesAllowed("network.configuration") + @Path("/factoryComponents") + @Produces(MediaType.APPLICATION_JSON) + public PidSet listFactoryComponentsPids() { + return new PidSet(Collections.emptySet()); + } + + @POST + @RolesAllowed("network.configuration") + @Path("/factoryComponents") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response createNetworkFactoryComponents(CreateFactoryComponentConfigurationsRequest configs) { + configs.validate(); + + final FailureHandler handler = new FailureHandler(); + + for (final FactoryComponentConfigurationDTO config : configs.getConfigs()) { + handler.runFallibleSubtask("create:" + config.getPid(), () -> { + + throw new KuraException(KuraErrorCode.INVALID_PARAMETER, + "Factory pid doesn't correspond to a network component factory"); + + }); + } + + if (configs.isTakeSnapshot()) { + handler.runFallibleSubtask(SUBTASK_SNAPSHOT_TAG, () -> this.configurationService.snapshot()); + } + + handler.checkStatus(); + return Response.ok().build(); + } + + @DELETE + @RolesAllowed("network.configuration") + @Path("/factoryComponents/byPid") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public Response deleteFactoryConfigurations(final DeleteFactoryComponentRequest request) { + request.validate(); + + final FailureHandler handler = new FailureHandler(); + + for (final String pid : request.getPids()) { + handler.runFallibleSubtask("delete:" + pid, () -> { + throw new KuraException(KuraErrorCode.INVALID_PARAMETER, + "Pid doesn't correspond to a network factory component"); + }); + } + + if (request.isTakeSnapshot()) { + handler.runFallibleSubtask(SUBTASK_SNAPSHOT_TAG, () -> this.configurationService.snapshot()); + } + + handler.checkStatus(); + return Response.ok().build(); + } + + @GET + @RolesAllowed("network.configuration") + @Path("/factoryComponents/ocd") + @Produces(MediaType.APPLICATION_JSON) + public ComponentConfigurationList getFactoryComponentOcds() { + + return DTOUtil.toComponentConfigurationList(Collections.emptyList(), this.cryptoService, false); + } + + @POST + @RolesAllowed("network.configuration") + @Path("/factoryComponents/ocd/byFactoryPid") + @Produces(MediaType.APPLICATION_JSON) + @Consumes(MediaType.APPLICATION_JSON) + public ComponentConfigurationList getFactoryComponentOcdsByPid(final PidSet factoryPids) { + factoryPids.validate(); + return DTOUtil.toComponentConfigurationList(Collections.emptyList(), this.cryptoService, false); + } + + /* + * Utils + */ + private boolean isNetworkConfigurationPid(String pid) { boolean result = false; for (String filter : NETWORK_CONFIGURATION_PIDS) { diff --git a/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/NetworkConfigurationRestServiceTest.java b/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/NetworkConfigurationRestServiceTest.java index 93932c1fb11..445a760d672 100644 --- a/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/NetworkConfigurationRestServiceTest.java +++ b/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/NetworkConfigurationRestServiceTest.java @@ -55,6 +55,7 @@ public class NetworkConfigurationRestServiceTest extends AbstractRequestHandlerT private static final String METHOD_SPEC_GET = "GET"; private static final String METHOD_SPEC_POST = "POST"; private static final String METHOD_SPEC_PUT = "PUT"; + private static final String METHOD_SPEC_DELETE = "DELETE"; private static final String REST_APP_ID = "networkConfiguration/v1"; private static final String NETWORK_CONF_SERVICE_PID = "org.eclipse.kura.net.admin.NetworkConfigurationService"; @@ -152,6 +153,64 @@ public void shouldUpdateWithoutErrors() throws KuraException { "1234,tcp,0:0:0:0:0:0:0:0/0,,,,,#"); } + @Test + public void shouldReturnEmptyArray() throws KuraException { + givenMockUpdateConfiguration(); + givenIdentity("admin", Optional.of("password"), Collections.emptyList()); + givenBasicCredentials(Optional.of("admin:password")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/factoryComponents"); + + thenResponseBodyEqualsJson(RestNetworkConfigurationJson.EMPTY_PIDS_RESPONSE); + } + + @Test + public void shouldReturnNothing() throws KuraException { + givenMockUpdateConfiguration(); + givenIdentity("admin", Optional.of("password"), Collections.emptyList()); + givenBasicCredentials(Optional.of("admin:password")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/factoryComponents", + RestNetworkConfigurationJson.EMPTY_CONFIGS_REQUEST); + + thenResponseCodeIs(200); + } + + @Test + public void shouldReturnInvalidPidResponse() throws KuraException { + givenMockUpdateConfiguration(); + givenIdentity("admin", Optional.of("password"), Collections.emptyList()); + givenBasicCredentials(Optional.of("admin:password")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_DELETE, "DEL"), "/factoryComponents/byPid", + RestNetworkConfigurationJson.INVALID_PID_DELETE_REQUEST); + + thenResponseBodyEqualsJson(RestNetworkConfigurationJson.INVALID_PID_DELETE_RESPONSE); + } + + @Test + public void shouldReturnEmptyConfigsOnGet() throws KuraException { + givenMockUpdateConfiguration(); + givenIdentity("admin", Optional.of("password"), Collections.emptyList()); + givenBasicCredentials(Optional.of("admin:password")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_GET), "/factoryComponents/ocd"); + + thenResponseBodyEqualsJson(RestNetworkConfigurationJson.EMPTY_CONFIGS_RESPONSE); + } + + @Test + public void shouldReturnEmptyConfigsOnPost() throws KuraException { + givenMockUpdateConfiguration(); + givenIdentity("admin", Optional.of("password"), Collections.emptyList()); + givenBasicCredentials(Optional.of("admin:password")); + + whenRequestIsPerformed(new MethodSpec(METHOD_SPEC_POST), "/factoryComponents/ocd/byFactoryPid", + RestNetworkConfigurationJson.EMPTY_PIDS_REQUEST); + + thenResponseBodyEqualsJson(RestNetworkConfigurationJson.EMPTY_CONFIGS_RESPONSE); + } + /* * Given */ diff --git a/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/responses/RestNetworkConfigurationJson.java b/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/responses/RestNetworkConfigurationJson.java index 0a7286aae45..c833b0d53fd 100644 --- a/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/responses/RestNetworkConfigurationJson.java +++ b/kura/test/org.eclipse.kura.rest.network.configuration.provider.test/src/main/java/org/eclipse/kura/rest/network/configuration/provider/test/responses/RestNetworkConfigurationJson.java @@ -22,10 +22,16 @@ private RestNetworkConfigurationJson() { */ public static final String FIREWALL_IP6_BYPID_REQUEST = "{\"pids\":[\"org.eclipse.kura.net.admin.ipv6.FirewallConfigurationServiceIPv6\"]}"; public static final String FIREWALL_IP6_UPDATE_REQUEST = "{\"configs\":[{\"pid\":\"org.eclipse.kura.net.admin.ipv6.FirewallConfigurationServiceIPv6\",properties: {\"firewall.ipv6.open.ports\":{\"type\":\"STRING\",\"value\":\"1234,tcp,0:0:0:0:0:0:0:0/0,,,,,#\"}}}]}"; + public static final String EMPTY_CONFIGS_REQUEST = "{\"configs\":[]}"; + public static final String INVALID_PID_DELETE_REQUEST = "{\"pids\":[\"invalidPid\"]}"; + public static final String EMPTY_PIDS_REQUEST = "{\"pids\":[]}"; /* * Responses */ public static final String ALL_CONFIGURATIONS_RESPONSE = "{\"configs\":[{\"pid\":\"CONF_COMP_PID_0\",\"definition\":{\"name\":\"OCD_MOCK_NAME_0\",\"description\":\"OCD_MOCK_DESC_0\",\"id\":\"OCD_MOCK_ID_0\"},\"properties\":{}},{\"pid\":\"CONF_COMP_PID_1\",\"definition\":{\"name\":\"OCD_MOCK_NAME_1\",\"description\":\"OCD_MOCK_DESC_1\",\"id\":\"OCD_MOCK_ID_1\"},\"properties\":{}},{\"pid\":\"CONF_COMP_PID_2\",\"definition\":{\"name\":\"OCD_MOCK_NAME_2\",\"description\":\"OCD_MOCK_DESC_2\",\"id\":\"OCD_MOCK_ID_2\"},\"properties\":{}}]}"; public static final String SINGLE_CONFIG_RESPONSE = "{\"configs\":[{\"pid\":\"CONF_COMP_PID_0\",\"definition\":{\"name\":\"OCD_MOCK_NAME_0\",\"description\":\"OCD_MOCK_DESC_0\",\"id\":\"OCD_MOCK_ID_0\"},\"properties\":{}}]}"; + public static final String EMPTY_PIDS_RESPONSE = "{\"pids\":[]}"; + public static final String INVALID_PID_DELETE_RESPONSE = "{\"failures\":[{\"id\":\"delete:invalidPid\",\"message\":\"Invalid parameter. Pid doesn't correspond to a network factory component\"}]}"; + public static final String EMPTY_CONFIGS_RESPONSE = "{\"configs\":[]}"; }