diff --git a/README.md b/README.md index e824971e9..639988af8 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,31 @@ Build: [![Circle CI](https://circleci.com/gh/eclipse/hawkbit.svg?style=svg)](htt * You can also check out our [Project Homepage](https://projects.eclipse.org/projects/iot.hawkbit) for further contact options. -# Compile -``` -mvn install -``` - -# Run and use +# Compile, Run and Getting Started We are not providing an off the shelf installation ready hawkBit update server. However, we recommend to check out the [Example Application](examples/hawkbit-example-app) for a runtime ready Spring Boot based update server that is empowered by hawkBit. +#### Clone and build hawkBit +``` +$ git clone https://github.com/eclipse/hawkbit.git +$ mvn clean install +``` +#### Start hawkBit example app +[Example Application](examples/hawkbit-example-app) +``` +$ java –jar ./examples/hawkbit-example-app/target/hawkbit-example-app-#version#.jar +``` +#### Start hawkBit device simulator +[Device Simulator](examples/hawkbit-device-simulator) +``` +$ java –jar ./examples/hawkbit-device-simulator/target/hawkbit-device-simulator-#version#.jar +``` +#### Generate Getting Started data +[Example Management API Client](examples/hawkbit-mgmt-api-client) +``` +$ java –jar ./examples/hawkbit-mgmt-api-client/target/hawkbit-mgmt-api-client-#version#.jar +``` + # Releases and Roadmap * We are currently working on the first formal release under the Eclipse banner: 0.1 (see [Release 0.1 branch](https://github.com/eclipse/hawkbit/tree/release-train-0.1)). @@ -29,11 +45,10 @@ We are not providing an off the shelf installation ready hawkBit update server. * And of course tons of usability improvements and bug fixes. -## Try out examples -#### Standalone Test Application Server -[Example Application](examples/hawkbit-example-app) -#### Device Simulator using the DMF AMQP API -[Device Simulator](examples/hawkbit-device-simulator) +# Device Integration +There are two device integration APIs provided by the hawkbit update server. +* [Direct Device Integration API (HTTP)](DDIA.md) +* [Device Management Federation API (AMQP)](DMFA.md) # Modules `hawkbit-core` : core elements. @@ -49,9 +64,3 @@ We are not providing an off the shelf installation ready hawkBit update server. `hawkbit-rest-resource` : HTTP REST endpoints for the Management and the Direct Device API. `hawkbit-ui` : Vaadin UI. `hawkbit-cache-redis` : spring cache manager configuration and implementation with redis, distributed cache and distributed events. - - -# Device Integration -There are two device integration APIs provided by the hawkbit update server. -* [Direct Device Integration API (HTTP)](DDIA.md) -* [Device Management Federation API (AMQP)](DMFA.md) diff --git a/examples/hawkbit-mgmt-api-client/README.md b/examples/hawkbit-mgmt-api-client/README.md index 7eb32f9e6..eff301e20 100644 --- a/examples/hawkbit-mgmt-api-client/README.md +++ b/examples/hawkbit-mgmt-api-client/README.md @@ -1,3 +1,39 @@ +# HawkBit management API example + Example client that shows how to efficiently use the hawkBit management API. -Powered by [Feign](https://github.com/Netflix/feign). \ No newline at end of file +Powered by [Feign](https://github.com/Netflix/feign). + +## How to run the example client + +Run getting started example + + + + $ java -jar hawkbit-mgmt-api-client-#version#.jar + + +Run create and start rollout example + + + $ java -jar hawkbit-mgmt-api-client-#version#.jar --createrollout + + +## This example shows + +In getting started example: +* creating software modules type +* creating distribution set type +* creating distribution sets +* creating software modules +* assigning software modules to distribution sets + +In rollout mode: +* creating software modules type +* creating distribution set type +* creating distribution sets +* creating software modules +* assigning software modules to distribution sets +* creating a rollout +* starting a rollout + diff --git a/examples/hawkbit-mgmt-api-client/pom.xml b/examples/hawkbit-mgmt-api-client/pom.xml index cced3dfbb..df55dc6ae 100644 --- a/examples/hawkbit-mgmt-api-client/pom.xml +++ b/examples/hawkbit-mgmt-api-client/pom.xml @@ -1,13 +1,6 @@ - + 4.0.0 @@ -16,9 +9,43 @@ hawkbit-examples-parent 0.2.0-SNAPSHOT + jar hawkbit-mgmt-api-client hawkBit Management API example client + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + ${baseDir} + false + org.eclipse.hawkbit.mgmt.client.Application + JAR + + + + + + + + + + + org.springframework.cloud + spring-cloud-netflix + 1.0.7.RELEASE + pom + import + + + @@ -26,45 +53,32 @@ hawkbit-rest-api ${project.version} - - com.netflix.feign - feign-jackson - 8.12.1 - com.netflix.feign feign-core - 8.12.1 + + 8.14.2 - - - org.eclipse.hawkbit - hawkbit-example-app - ${project.version} - test + hibernate-validator + org.hibernate org.springframework.boot - spring-boot-starter-test - test + spring-boot-starter - ru.yandex.qatools.allure - allure-junit-adaptor - test + org.springframework.cloud + spring-cloud-starter-feign - org.easytesting - fest-assert-core - test + org.springframework.boot + spring-boot-starter-logging - org.easytesting - fest-assert - test + com.google.collections + google-collections + 1.0-rc2 - - \ No newline at end of file diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/DistributionSetResource.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/DistributionSetResource.java deleted file mode 100644 index 62c987ae8..000000000 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/DistributionSetResource.java +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import java.util.List; - -import org.eclipse.hawkbit.rest.resource.RestConstants; -import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost; -import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; - -import feign.Headers; -import feign.RequestLine; - -/** - * Client binding for the Distribution resource of the management API. - */ -@FunctionalInterface -public interface DistributionSetResource { - - /** - * Creates a list of distribution sets. - * - * @param sets - * the request body java bean containing the necessary attributes - * for creating a distribution set. - * @return the list of targets which have been created - */ - @RequestLine("POST " + RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) - @Headers("Content-Type: application/json") - DistributionSetsRest createDistributionSets(final List sets); - -} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/DistrubutionSetTagResource.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/DistrubutionSetTagResource.java deleted file mode 100644 index fe7a147a8..000000000 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/DistrubutionSetTagResource.java +++ /dev/null @@ -1,138 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import java.util.List; - -import org.eclipse.hawkbit.rest.resource.RestConstants; -import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; -import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; -import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; - -import feign.Headers; -import feign.Param; -import feign.RequestLine; - -/** - * Client binding for the DistributionSetTag resource of the management API. - */ -public interface DistrubutionSetTagResource { - - /** - * Retrieves a single distributionset tag based on the given ID. - * - * @param dsTagId - * the ID of the distributionset tag to retrieve - * @return a deserialized java bean containing the attributes of the - * returned distributionset tag - */ - @RequestLine("GET " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{dsTagId}") - TagRest getDistributionSetTag(@Param("dsTagId") Long dsTagId); - - /** - * Creates a list of distributionset tags. - * - * @param tags - * the tags to be created - * @return the created tag list - */ - @RequestLine("POST " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) - @Headers("Content-Type: application/json") - TagsRest createDistributionSetTags(List tags); - - /** - * Update attributes of a distributionset tag. - * - * @param dsTagId - * the distributionset tag id to be updated - * @param tag - * the request body - * @return the updated distributionset tag - */ - @RequestLine("PUT " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{dsTagId}") - @Headers("Content-Type: application/json") - TagRest updateDistributionSetTag(@Param("dsTagId") Long dsTagId, TagRequestBodyPut tag); - - /** - * Deletes given distributionset tag on given ID. - * - * @param dsTagId - * to be deleted - */ - @RequestLine("DELETE " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{dsTagId}") - void deleteDistributionSetTag(@Param("dsTagId") final Long dsTagId); - - /** - * Retrieves a all assigned targets on the given distributionset tag id. - * - * @param dsTagId - * the ID of the distributionset tag to retrieve - * @return a list of targets - */ - @RequestLine("GET " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING - + RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) - DistributionSetsRest getAssignedDistributionSets(@Param("dsTagId") final Long dsTagId); - - /** - * Toggle the tag assignment all assigned targets will be unassigned and all - * unassigned targets will be assigned. - * - * @param dsTagId - * the ID of the distributionset tag to toggle - * @param assignedTargetRequestBodies - * a list of controller ids - * @return a list of assigned and unassigned targets - */ - @RequestLine("POST " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING - + RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING + "/toggleTagAssignment") - @Headers("Content-Type: application/json") - DistributionSetTagAssigmentResultRest toggleTagAssignment(@Param("dsTagId") final Long dsTagId, - final List assignedTargetRequestBodies); - - /** - * Assign targets to a given distributionset tag id. - * - * @param dsTagId - * the ID of the distributionset tag to add the targets - * @param assignedTargetRequestBodies - * a list of controller ids - * @return a list of assigned targets - */ - @RequestLine("POST " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING - + RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) - @Headers("Content-Type: application/json") - TargetsRest assignDistributionSets(@Param("dsTagId") final Long dsTagId, - final List assignedTargetRequestBodies); - - /** - * Unassign targets to a given distributionset tag id. - * - * @param dsTagId - * the ID of the distributionset tag to add the targets - */ - @RequestLine("DELETE " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING - + RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) - void unassignDistributionSets(@Param("dsTagId") final Long dsTagId); - - /** - * Unassign one target to a given distributionset tag id. - * - * @param dsTagId - * the ID of the distributionset tag to add the targets param - * @param dsId - * the distributionset id - */ - @RequestLine("DELETE " + RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING - + RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING + "/{dsId}") - void unassignDistributionSet(@Param("dsTagId") final Long dsTagId, @Param("dsId") final Long dsId); -} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/TargetResource.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/TargetResource.java deleted file mode 100644 index 66c147426..000000000 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/TargetResource.java +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import java.util.List; - -import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList; -import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.target.TargetRest; -import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; - -import feign.Headers; -import feign.Param; -import feign.RequestLine; - -/** - * Client binding for the Target resource of the management API. - */ -public interface TargetResource { - - /** - * Retrieves a single target based on the given ID. - * - * @param targetId - * the ID of the target to retrieve - * @return a deserialized java bean containing the attributes of the - * returned target - */ - @RequestLine("GET /rest/v1/targets/{targetId}") - TargetRest getTarget(@Param("targetId") final String targetId); - - /** - * Paged query of targets resource. - * - * @param pagingOffsetParam - * of the paged query - * @param pagingLimitParam - * of the paged query - * @return paged list of target entries - */ - @RequestLine("GET /rest/v1/targets?offset={pagingOffsetParam}&limit={pagingLimitParam}") - TargetPagedList getTargets(@Param("pagingOffsetParam") int pagingOffsetParam, - @Param("pagingLimitParam") int pagingLimitParam); - - /** - * Paged query of targets resource with default offset and limit. - * - * @return paged list of target entries - */ - @RequestLine("GET /rest/v1/targets") - TargetPagedList getTargets(); - - /** - * Deletes given target based on given ID. - * - * @param targetId - * to be deleted - */ - @RequestLine("DELETE /rest/v1/targets/{targetId}") - void deleteTarget(@Param("targetId") final String targetId); - - /** - * Creates a list of targets. - * - * @param targets - * the request body java bean containing the necessary attributes - * for creating a target. - * @return the list of targets which have been created - */ - @RequestLine("POST /rest/v1/targets/") - @Headers("Content-Type: application/json") - TargetsRest createTargets(List targets); - -} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/TargetTagResource.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/TargetTagResource.java deleted file mode 100644 index bd74e52d7..000000000 --- a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/api/client/TargetTagResource.java +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import java.util.List; - -import org.eclipse.hawkbit.rest.resource.RestConstants; -import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TargetTagAssigmentResultRest; -import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; - -import feign.Headers; -import feign.Param; -import feign.RequestLine; - -/** - * Client binding for the Target resource of the management API. - */ -public interface TargetTagResource { - - /** - * Retrieves a single target tag based on the given ID. - * - * @param targetTagId - * the ID of the target tag to retrieve - * @return a deserialized java bean containing the attributes of the - * returned target tag - */ - @RequestLine("GET " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}") - TagRest getTargetTag(@Param("targetTagId") Long targetTagId); - - /** - * Creates a list of target tags. - * - * @param tags - * the tags to be created - * @return the created tag list - */ - @RequestLine("POST " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING) - @Headers("Content-Type: application/json") - TagsRest createTargetTag(List tags); - - /** - * Update attributes of a target tag. - * - * @param targetTagId - * the target tag id to be updated - * @param tag - * the request body - * @return the updated target tag - */ - @RequestLine("PUT " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}") - @Headers("Content-Type: application/json") - TagRest updateTagretTag(@Param("targetTagId") Long targetTagId, TagRequestBodyPut tag); - - /** - * Deletes given target tag on given ID. - * - * @param targetTagId - * to be deleted - */ - @RequestLine("DELETE " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}") - void deleteTargetTag(@Param("targetTagId") final Long targetTagId); - - /** - * Retrieves a all assigned targets on the given target tag id. - * - * @param targetTagId - * the ID of the target tag to retrieve - * @return a list of targets - */ - @RequestLine("GET " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING - + RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING) - TargetsRest getAssignedTargets(@Param("targetTagId") final Long targetTagId); - - /** - * Toggle the tag assignment all assigned targets will be unassigned and all - * unassigned targets will be assigned. - * - * @param targetTagId - * the ID of the target tag to toggle - * @param assignedTargetRequestBodies - * a list of controller ids - * @return a list of assigned and unassigned targets - */ - @RequestLine("POST " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING - + RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/toggleTagAssignment") - @Headers("Content-Type: application/json") - TargetTagAssigmentResultRest toggleTagAssignment(@Param("targetTagId") final Long targetTagId, - final List assignedTargetRequestBodies); - - /** - * Assign targets to a given target tag id. - * - * @param targetTagId - * the ID of the target tag to add the targets - * @param assignedTargetRequestBodies - * a list of controller ids - * @return a list of assigned targets - */ - @RequestLine("POST " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING - + RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING) - @Headers("Content-Type: application/json") - TargetsRest assignTargets(@Param("targetTagId") final Long targetTagId, - final List assignedTargetRequestBodies); - - /** - * Unassign targets to a given target tag id. - * - * @param targetTagId - * the ID of the target tag to add the targets - */ - @RequestLine("DELETE " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING - + RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING) - void unassignTargets(@Param("targetTagId") final Long targetTagId); - - /** - * Unassign one target to a given target tag id. - * - * @param targetTagId - * the ID of the target tag to add the targets param - * @param controllerId - * the controller id - */ - @RequestLine("DELETE " + RestConstants.TARGET_TAG_V1_REQUEST_MAPPING - + RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/{controllerId}") - void unassignTarget(@Param("targetTagId") final Long targetTagId, @Param("controllerId") final String controllerId); -} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java new file mode 100644 index 000000000..27584b50a --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/Application.java @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client; + +import org.eclipse.hawkbit.mgmt.client.scenarios.CreateStartedRolloutExample; +import org.eclipse.hawkbit.mgmt.client.scenarios.GettingStartedDefaultScenario; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.netflix.feign.EnableFeignClients; +import org.springframework.context.annotation.Bean; + +import feign.Contract; +import feign.auth.BasicAuthRequestInterceptor; + +@SpringBootApplication +@EnableFeignClients +@EnableConfigurationProperties(ClientConfigurationProperties.class) +public class Application implements CommandLineRunner { + + @Autowired + private ClientConfigurationProperties configuration; + + @Autowired + private GettingStartedDefaultScenario gettingStarted; + + @Autowired + private CreateStartedRolloutExample gettingStartedRolloutScenario; + + public static void main(final String[] args) { + new SpringApplicationBuilder().showBanner(false).sources(Application.class).run(args); + } + + @Override + public void run(final String... args) throws Exception { + if (containsArg("--createrollout", args)) { + // run the create and start rollout example + gettingStartedRolloutScenario.run(); + } else { + // run the getting started scenario which creates a setup of + // distribution set and software modules to be used + gettingStarted.run(); + } + } + + @Bean + public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { + return new BasicAuthRequestInterceptor(configuration.getUsername(), configuration.getPassword()); + } + + @Bean + public ApplicationJsonRequestHeaderInterceptor jsonHeaderInterceptor() { + return new ApplicationJsonRequestHeaderInterceptor(); + } + + @Bean + public Contract feignContract() { + return new IgnoreMultipleConsumersProducersSpringMvcContract(); + } + + private boolean containsArg(final String containsArg, final String... args) { + for (final String arg : args) { + if (arg.equalsIgnoreCase(containsArg)) { + return true; + } + } + return false; + } +} \ No newline at end of file diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/ApplicationJsonRequestHeaderInterceptor.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/ApplicationJsonRequestHeaderInterceptor.java new file mode 100644 index 000000000..75f3b0dd1 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/ApplicationJsonRequestHeaderInterceptor.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client; + +import org.springframework.http.MediaType; + +import feign.RequestInterceptor; +import feign.RequestTemplate; + +/** + * An feign request interceptor to set the defined {@code Accept} and + * {@code Content-Type} headers for each request to {@code application/json}. + */ +public class ApplicationJsonRequestHeaderInterceptor implements RequestInterceptor { + + @Override + public void apply(final RequestTemplate template) { + template.header("Accept", MediaType.APPLICATION_JSON_VALUE); + template.header("Content-Type", MediaType.APPLICATION_JSON_VALUE); + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java new file mode 100644 index 000000000..6d15bcc04 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/ClientConfigurationProperties.java @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Configuration bean which holds the configuration of the client e.g. the base + * URL of the hawkbit-server and the credentials to use the RESTful Management + * API. + */ +@ConfigurationProperties(prefix = "hawkbit") +public class ClientConfigurationProperties { + + private String url = "localhost:8080"; + private String username = "admin"; + private String password = "admin"; // NOSONAR this password is only used for + // examples + + public String getUrl() { + return url; + } + + public void setUrl(final String url) { + this.url = url; + } + + public String getUsername() { + return username; + } + + public void setUsername(final String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(final String password) { + this.password = password; + } +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/IgnoreMultipleConsumersProducersSpringMvcContract.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/IgnoreMultipleConsumersProducersSpringMvcContract.java new file mode 100644 index 000000000..c796aa019 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/IgnoreMultipleConsumersProducersSpringMvcContract.java @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cloud.netflix.feign.support.SpringMvcContract; + +import feign.MethodMetadata; + +/** + * Own implementation of the {@link SpringMvcContract} which catches the + * {@link IllegalStateException} which occurs due multiple produces and consumes + * values in the request-mapping + * annoation.https://github.com/spring-cloud/spring-cloud-netflix/issues/808 + */ +public class IgnoreMultipleConsumersProducersSpringMvcContract extends SpringMvcContract { + + private static final Logger LOGGER = LoggerFactory + .getLogger(IgnoreMultipleConsumersProducersSpringMvcContract.class); + + @Override + protected void processAnnotationOnMethod(final MethodMetadata data, final Annotation methodAnnotation, + final Method method) { + try { + super.processAnnotationOnMethod(data, methodAnnotation, method); + } catch (final IllegalStateException e) { + // ignore illegalstateexception here because it's thrown because of + // multiple consumers and produces, see + // https://github.com/spring-cloud/spring-cloud-netflix/issues/808 + LOGGER.trace(e.getMessage(), e); + } + } +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java new file mode 100644 index 000000000..00a9b3fba --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetResourceClient.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the DistributionSet resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsets") +public interface DistributionSetResourceClient extends DistributionSetRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java new file mode 100644 index 000000000..ea9f5d28a --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTagResourceClient.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTagRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the DistributionSetTag resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsettags") +public interface DistributionSetTagResourceClient extends DistributionSetTagRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java new file mode 100644 index 000000000..78e3df1c2 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/DistributionSetTypeResourceClient.java @@ -0,0 +1,16 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the DistributionSetType resource of the management API. + * + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/distributionsettypes") +public interface DistributionSetTypeResourceClient extends DistributionSetTypeRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java new file mode 100644 index 000000000..0124bb383 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/RolloutResourceClient.java @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.RolloutRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the Rollout resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/rollouts") +public interface RolloutResourceClient extends RolloutRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java new file mode 100644 index 000000000..9ffbe2a1a --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleResourceClient.java @@ -0,0 +1,15 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleRestAPI; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the SoftwareModule resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/softwaremodules") +public interface SoftwareModuleResourceClient extends SoftwareModuleRestAPI { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java new file mode 100644 index 000000000..4896cb8d8 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/SoftwareModuleTypeResourceClient.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the oftwareModuleType resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/softwaremoduletypes") +public interface SoftwareModuleTypeResourceClient extends SoftwareModuleTypeRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java new file mode 100644 index 000000000..a82aa5443 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetResourceClient.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.TargetRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the Target resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/targets") +public interface TargetResourceClient extends TargetRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java new file mode 100644 index 000000000..fee30c686 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/TargetTagResourceClient.java @@ -0,0 +1,20 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.mgmt.client.resource; + +import org.eclipse.hawkbit.rest.resource.api.TargetTagRestApi; +import org.springframework.cloud.netflix.feign.FeignClient; + +/** + * Client binding for the TargetTag resource of the management API. + */ +@FeignClient(url = "${hawkbit.endpoint.url:localhost:8080}/rest/v1/targettags") +public interface TargetTagResourceClient extends TargetTagRestApi { + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java new file mode 100644 index 000000000..772256175 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetBuilder.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost; + +import com.google.common.collect.Lists; + +/** + * + * Builder pattern for building {@link DistributionSetRequestBodyPost}. + * + * @author Jonathan Knoblauch + * + */ +public class DistributionSetBuilder { + + private String name; + private String version; + private String type; + + /** + * @param name + * the name of the distribution set + * @return the builder itself + */ + public DistributionSetBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * @param version + * the version of the distribution set + * @return the builder itself + */ + public DistributionSetBuilder version(final String version) { + this.version = version; + return this; + } + + /** + * @param type + * the distribution set type name for this distribution set + * @return the builder itself + */ + public DistributionSetBuilder type(final String type) { + this.type = type; + return this; + } + + /** + * Builds a list with a single entry of + * {@link DistributionSetRequestBodyPost} which can directly be used to post + * on the RESTful-API. + * + * @return a single entry list of {@link DistributionSetRequestBodyPost} + */ + public List build() { + return Lists.newArrayList(doBuild(name)); + } + + /** + * Builds a list of multiple {@link DistributionSetRequestBodyPost} to + * create multiple distribution sets at once. An increasing number will be + * added to the name of the distribution set. The version and type will + * remain the same. + * + * @param count + * the amount of distribution sets body which should be created + * @return a list of {@link DistributionSetRequestBodyPost} + */ + public List buildAsList(final int count) { + final ArrayList bodyList = Lists.newArrayList(); + for (int index = 0; index < count; index++) { + bodyList.add(doBuild(name + index)); + } + + return bodyList; + } + + private DistributionSetRequestBodyPost doBuild(final String prefixName) { + final DistributionSetRequestBodyPost body = new DistributionSetRequestBodyPost(); + body.setName(prefixName); + body.setVersion(version); + body.setType(type); + return body; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java new file mode 100644 index 000000000..0ba326c16 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/DistributionSetTypeBuilder.java @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeAssigmentRest; + +import com.google.common.collect.Lists; + +/** + * + * Builder pattern for building {@link DistributionSetTypeRequestBodyPost}. + * + * @author Jonathan Knoblauch + * + */ +public class DistributionSetTypeBuilder { + + private String key; + private String name; + private final List mandatorymodules = Lists.newArrayList(); + private final List optionalmodules = Lists.newArrayList(); + + /** + * @param key + * the key of the distribution set type + * @return the builder itself + */ + public DistributionSetTypeBuilder key(final String key) { + this.key = key; + return this; + } + + /** + * @param name + * the name of the distribution set type + * @return the builder itself + */ + public DistributionSetTypeBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * @param softwareModuleTypeIds + * the IDs of the software module types which should be mandatory + * for the distribution set type + * @return the builder itself + */ + public DistributionSetTypeBuilder mandatorymodules(final Long... softwareModuleTypeIds) { + for (final Long id : softwareModuleTypeIds) { + final SoftwareModuleTypeAssigmentRest softwareModuleTypeAssigmentRest = new SoftwareModuleTypeAssigmentRest(); + softwareModuleTypeAssigmentRest.setId(id); + this.mandatorymodules.add(softwareModuleTypeAssigmentRest); + } + return this; + } + + /** + * + * @param softwareModuleTypeIds + * the IDs of the software module types which should be optional + * for the distribution set type + * @return the builder itself + */ + public DistributionSetTypeBuilder optionalmodules(final Long... softwareModuleTypeIds) { + for (final Long id : softwareModuleTypeIds) { + final SoftwareModuleTypeAssigmentRest softwareModuleTypeAssigmentRest = new SoftwareModuleTypeAssigmentRest(); + softwareModuleTypeAssigmentRest.setId(id); + this.optionalmodules.add(softwareModuleTypeAssigmentRest); + } + return this; + } + + /** + * Builds a list with a single entry of + * {@link DistributionSetTypeRequestBodyPost} which can directly be used in + * the RESTful-API. + * + * @return a single entry list of {@link DistributionSetTypeRequestBodyPost} + */ + public List build() { + return Lists.newArrayList(doBuild(name, key)); + } + + /** + * Builds a list of multiple {@link DistributionSetTypeRequestBodyPost} to + * create multiple distribution set types at once. An increasing number will + * be added to the name and key of the distribution set type. The optional + * and mandatory software module types will remain the same. + * + * @param count + * the amount of distribution sets type body which should be + * created + * @return a list of {@link DistributionSetTypeRequestBodyPost} + */ + public List buildAsList(final int count) { + final ArrayList bodyList = Lists.newArrayList(); + for (int index = 0; index < count; index++) { + bodyList.add(doBuild(name + index, key + index)); + } + return bodyList; + + } + + private DistributionSetTypeRequestBodyPost doBuild(final String prefixName, final String prefixKey) { + final DistributionSetTypeRequestBodyPost body = new DistributionSetTypeRequestBodyPost(); + body.setKey(prefixKey); + body.setName(prefixName); + body.setMandatorymodules(mandatorymodules); + body.setOptionalmodules(optionalmodules); + return body; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java new file mode 100644 index 000000000..73f327db9 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/RolloutBuilder.java @@ -0,0 +1,110 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutCondition; +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutCondition.Condition; +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody; + +/** + * + * Builder pattern for building {@link RolloutRestRequestBody}. + * + * @author Jonathan Knoblauch + * + */ +public class RolloutBuilder { + + private String name; + private int groupSize; + private String targetFilterQuery; + private long distributionSetId; + private String successThreshold; + private String errorThreshold; + + /** + * @param name + * the name of the rollout + * @return the builder itself + */ + public RolloutBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * @param groupSize + * the amount of groups the rollout should be split into + * @return the builder itself + */ + public RolloutBuilder groupSize(final int groupSize) { + this.groupSize = groupSize; + return this; + } + + /** + * @param targetFilterQuery + * the FIQL query language to filter targets to contain in the + * rollout + * @return the builder itself + */ + public RolloutBuilder targetFilterQuery(final String targetFilterQuery) { + this.targetFilterQuery = targetFilterQuery; + return this; + } + + /** + * @param distributionSetId + * the ID of the distribution set to assign to the target in the + * rollout + * @return the builder itself + */ + public RolloutBuilder distributionSetId(final long distributionSetId) { + this.distributionSetId = distributionSetId; + return this; + } + + /** + * @param successThreshold + * the threshold to be used to indicate if a deployment group is + * successful, to trigger the success action + * @return the builder itself + */ + public RolloutBuilder successThreshold(final String successThreshold) { + this.successThreshold = successThreshold; + return this; + } + + /** + * @param errorThreshold + * the threshold to be used to indicate if a deployment group is + * failing, to trigger the error action + * @return the builder itself + */ + public RolloutBuilder errorThreshold(final String errorThreshold) { + this.errorThreshold = errorThreshold; + return this; + } + + /** + * Builds the rollout rest body to creating a rollout. + * + * @return the rest request body for creating a rollout + */ + public RolloutRestRequestBody build() { + return doBuild(); + } + + private RolloutRestRequestBody doBuild() { + final RolloutRestRequestBody body = new RolloutRestRequestBody(); + body.setName(name); + body.setAmountGroups(groupSize); + body.setTargetFilterQuery(targetFilterQuery); + body.setDistributionSetId(distributionSetId); + body.setSuccessCondition(new RolloutCondition(Condition.THRESHOLD, successThreshold)); + body.setErrorCondition(new RolloutCondition(Condition.THRESHOLD, errorThreshold)); + return body; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java new file mode 100644 index 000000000..0086ae93b --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleAssigmentBuilder.java @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleAssigmentRest; + +/** + * + * Builder pattern for building {@link SoftwareModuleAssigmentRest}. + * + * @author Jonathan Knoblauch + * + */ +public class SoftwareModuleAssigmentBuilder { + + private final List ids; + + public SoftwareModuleAssigmentBuilder() { + ids = new ArrayList(); + } + + /** + * @param id + * the id of the software module + * @return the builder itself + */ + public SoftwareModuleAssigmentBuilder id(final Long id) { + ids.add(id); + return this; + } + + /** + * Builds a list with a single entry of {@link SoftwareModuleAssigmentRest} + * which can directly be used in the RESTful-API. + * + * @return a single entry list of {@link SoftwareModuleAssigmentRest} + */ + public List build() { + final List softwareModuleAssigmentRestList = new ArrayList<>(); + for (final Long id : ids) { + final SoftwareModuleAssigmentRest softwareModuleAssigmentRest = new SoftwareModuleAssigmentRest(); + softwareModuleAssigmentRest.setId(id); + softwareModuleAssigmentRestList.add(softwareModuleAssigmentRest); + } + return softwareModuleAssigmentRestList; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java new file mode 100644 index 000000000..f293e910f --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleBuilder.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPost; + +import com.google.common.collect.Lists; + +/** + * + * Builder pattern for building {@link SoftwareModuleRequestBodyPost}. + * + * @author Jonathan Knoblauch + * + */ +public class SoftwareModuleBuilder { + + private String name; + private String version; + private String type; + + /** + * @param name + * the name of the software module + * @return the builder itself + */ + public SoftwareModuleBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * @param version + * the version of the software module + * @return the builder itsefl + */ + public SoftwareModuleBuilder version(final String version) { + this.version = version; + return this; + } + + /** + * @param type + * the key of the software module type to be used for this + * software module + * @return the builder itself + */ + public SoftwareModuleBuilder type(final String type) { + this.type = type; + return this; + } + + /** + * Builds a list with a single entry of + * {@link SoftwareModuleRequestBodyPost} which can directly be used in the + * RESTful-API. + * + * @return a single entry list of {@link SoftwareModuleRequestBodyPost} + */ + public List build() { + return Lists.newArrayList(doBuild(name)); + } + + /** + * Builds a list of multiple {@link SoftwareModuleRequestBodyPost} to create + * multiple software module at once. An increasing number will be added to + * the name of the software module. The version and type will remain the + * same. + * + * @param count + * the amount of software module body which should be created + * @return a list of {@link DistributionSetTypeRequestBodyPost} + */ + public List buildAsList(final int count) { + final ArrayList bodyList = Lists.newArrayList(); + for (int index = 0; index < count; index++) { + bodyList.add(doBuild(name + index)); + } + + return bodyList; + } + + private SoftwareModuleRequestBodyPost doBuild(final String prefixName) { + final SoftwareModuleRequestBodyPost body = new SoftwareModuleRequestBodyPost(); + body.setName(prefixName); + body.setVersion(version); + body.setType(type); + return body; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java new file mode 100644 index 000000000..7222dc522 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/SoftwareModuleTypeBuilder.java @@ -0,0 +1,96 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost; + +import com.google.common.collect.Lists; + +/** + * + * Builder pattern for building {@link SoftwareModuleRequestBodyPost}. + * + * @author Jonathan Knoblauch + * + */ +public class SoftwareModuleTypeBuilder { + + private String key; + private String name; + private String description; + private int maxAssignments; + + /** + * @param key + * the key of the software module type + * @return the builder itself + */ + public SoftwareModuleTypeBuilder key(final String key) { + this.key = key; + return this; + } + + /** + * @param name + * the name of the software module type + * @return the builder itself + */ + public SoftwareModuleTypeBuilder name(final String name) { + this.name = name; + return this; + } + + public SoftwareModuleTypeBuilder description(final String description) { + this.description = description; + return this; + } + + public SoftwareModuleTypeBuilder maxAssignments(final int maxAssignments) { + this.maxAssignments = maxAssignments; + return this; + } + + /** + * Builds a list with a single entry of + * {@link SoftwareModuleTypeRequestBodyPost} which can directly be used in + * the RESTful-API. + * + * @return a single entry list of {@link SoftwareModuleTypeRequestBodyPost} + */ + public List build() { + return Lists.newArrayList(doBuild(key, name)); + } + + /** + * Builds a list of multiple {@link SoftwareModuleTypeRequestBodyPost} to + * create multiple software module types at once. An increasing number will + * be added to the name and key of the software module type. + * + * @param count + * the amount of software module type bodies which should be + * created + * @return a list of {@link SoftwareModuleTypeRequestBodyPost} + */ + public List buildAsList(final int count) { + final ArrayList bodyList = Lists.newArrayList(); + for (int index = 0; index < count; index++) { + bodyList.add(doBuild(key + index, name + index)); + } + return bodyList; + } + + private SoftwareModuleTypeRequestBodyPost doBuild(final String prefixKey, final String prefixName) { + final SoftwareModuleTypeRequestBodyPost body = new SoftwareModuleTypeRequestBodyPost(); + body.setKey(prefixKey); + body.setName(prefixName); + body.setDescription(description); + body.setMaxAssignments(maxAssignments); + return body; + } + +} \ No newline at end of file diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java new file mode 100644 index 000000000..af2926337 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TagBuilder.java @@ -0,0 +1,91 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; + +import com.google.common.collect.Lists; + +/** + * Builder pattern for building {@link TagRequestBodyPut}. + * + * @author Jonathan Knoblauch + * + */ +public class TagBuilder { + + private String name; + private String description; + private String color; + + /** + * @param name + * the name of the tag + * @return the builder itself + */ + public TagBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * @param description + * the description of the tag + * @return the builder itself + */ + public TagBuilder description(final String description) { + this.description = description; + return this; + } + + /** + * @param color + * the colour of the tag + * @return the builder itself + */ + public TagBuilder color(final String color) { + this.color = color; + return this; + } + + /** + * Builds a list with a single entry of {@link TagRequestBodyPut} which can + * directly be used in the RESTful-API. + * + * @return a single entry list of {@link TagRequestBodyPut} + */ + public List build() { + return Lists.newArrayList(doBuild(name)); + } + + /** + * Builds a list of multiple {@link TagRequestBodyPut} to create multiple + * tags at once. An increasing number will be added to the name of the tag. + * The color and description will remain the same. + * + * @param count + * the amount of distribution sets body which should be created + * @return a list of {@link TagRequestBodyPut} + */ + public List buildAsList(final int count) { + final ArrayList bodyList = Lists.newArrayList(); + for (int index = 0; index < count; index++) { + bodyList.add(doBuild(name + index)); + } + + return bodyList; + } + + private TagRequestBodyPut doBuild(final String prefixName) { + final TagRequestBodyPut body = new TagRequestBodyPut(); + body.setName(prefixName); + body.setDescription(description); + body.setColour(color); + return body; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java new file mode 100644 index 000000000..15e970fba --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/resource/builder/TargetBuilder.java @@ -0,0 +1,93 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.resource.builder; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody; + +import com.google.common.collect.Lists; + +/** + * + * Builder pattern for building {@link TargetRequestBody}. + * + * @author Jonathan Knoblauch + * + */ +public class TargetBuilder { + + private String controllerId; + private String name; + private String description; + + /** + * @param controllerId + * the ID of the controller/target + * @return the builder itself + */ + public TargetBuilder controllerId(final String controllerId) { + this.controllerId = controllerId; + return this; + } + + /** + * @param name + * the name of the target + * @return the builder itself + */ + public TargetBuilder name(final String name) { + this.name = name; + return this; + } + + /** + * @param description + * the description of the target + * @return the builder itself + */ + public TargetBuilder description(final String description) { + this.description = description; + return this; + } + + /** + * Builds a list with a single entry of {@link TargetRequestBody} which can + * directly be used in the RESTful-API. + * + * @return a single entry list of {@link TargetRequestBody} + */ + public List build() { + return Lists.newArrayList(doBuild(controllerId)); + } + + /** + * Builds a list of multiple {@link TargetRequestBody} to create multiple + * targets at once. An increasing number will be added to the controllerId + * of the target. The name and description will remain. + * + * @param count + * the amount of software module type bodies which should be + * created + * @return a list of {@link SoftwareModuleTypeRequestBodyPost} + */ + public List buildAsList(final int count) { + final ArrayList bodyList = Lists.newArrayList(); + for (int index = 0; index < count; index++) { + bodyList.add(doBuild(controllerId + index)); + } + return bodyList; + } + + private TargetRequestBody doBuild(final String prefixControllerId) { + final TargetRequestBody body = new TargetRequestBody(); + body.setControllerId(prefixControllerId); + body.setName(name); + body.setDescription(description); + return body; + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java new file mode 100644 index 000000000..1414281ee --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/CreateStartedRolloutExample.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2011-2016 Bosch Software Innovations GmbH, Germany. All rights reserved. + */ +package org.eclipse.hawkbit.mgmt.client.scenarios; + +import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetTypeResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.RolloutResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleTypeResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.TargetResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetTypeBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.RolloutBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleTypeBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.TargetBuilder; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutResponseBody; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulesRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * Example for creating and starting a Rollout. + * + */ +@Component +public class CreateStartedRolloutExample { + + /* known software module type name and key */ + private static final String SM_MODULE_TYPE = "firmware"; + + /* known distribution set type name and key */ + private static final String DS_MODULE_TYPE = "firmware"; + + @Autowired + private DistributionSetResourceClient distributionSetResource; + + @Autowired + private SoftwareModuleResourceClient softwareModuleResource; + + @Autowired + private TargetResourceClient targetResource; + + @Autowired + private RolloutResourceClient rolloutResource; + + @Autowired + private DistributionSetTypeResourceClient distributionSetTypeResource; + + @Autowired + private SoftwareModuleTypeResourceClient softwareModuleTypeResource; + + /** + * Run the Rollout scenario. + */ + public void run() { + + // create three SoftwareModuleTypes + final SoftwareModuleTypesRest createdSoftwareModuleTypes = softwareModuleTypeResource.createSoftwareModuleTypes( + new SoftwareModuleTypeBuilder().key(SM_MODULE_TYPE).name(SM_MODULE_TYPE).maxAssignments(1).build()) + .getBody(); + + // create one DistributionSetType + distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(DS_MODULE_TYPE) + .name(DS_MODULE_TYPE).mandatorymodules(createdSoftwareModuleTypes.get(0).getModuleId()).build()) + .getBody(); + + // create one DistributionSet + final DistributionSetsRest distributionSetsRest = distributionSetResource.createDistributionSets( + new DistributionSetBuilder().name("rollout-example").version("1.0.0").type(DS_MODULE_TYPE).build()) + .getBody(); + + // create three SoftwareModules + final SoftwareModulesRest softwareModulesRest = softwareModuleResource + .createSoftwareModules( + new SoftwareModuleBuilder().name("firmware").version("1.0.0").type(SM_MODULE_TYPE).build()) + .getBody(); + + // Assign SoftwareModule to DistributionSet + distributionSetResource.assignSoftwareModules(distributionSetsRest.get(0).getDsId(), + new SoftwareModuleAssigmentBuilder().id(softwareModulesRest.get(0).getModuleId()).build()); + + // create ten targets + targetResource.createTargets(new TargetBuilder().controllerId("00-FF-AA-0").name("00-FF-AA-0") + .description("Targets used for rollout example").buildAsList(10)); + + // create a Rollout + final RolloutResponseBody rolloutResponseBody = rolloutResource + .create(new RolloutBuilder().name("MyRollout").groupSize(2).targetFilterQuery("name==00-FF-AA-0*") + .distributionSetId(distributionSetsRest.get(0).getDsId()).successThreshold("80") + .errorThreshold("50").build()) + .getBody(); + + // start the created Rollout + rolloutResource.start(rolloutResponseBody.getRolloutId(), false); + } + +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java new file mode 100644 index 000000000..2d3e071ed --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/java/org/eclipse/hawkbit/mgmt/client/scenarios/GettingStartedDefaultScenario.java @@ -0,0 +1,126 @@ +package org.eclipse.hawkbit.mgmt.client.scenarios; + +import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.DistributionSetTypeResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.SoftwareModuleTypeResourceClient; +import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.DistributionSetTypeBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleAssigmentBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleBuilder; +import org.eclipse.hawkbit.mgmt.client.resource.builder.SoftwareModuleTypeBuilder; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulesRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +/** + * + * Default getting started scenario. + * + */ +@Component +public class GettingStartedDefaultScenario { + + private static final Logger LOGGER = LoggerFactory.getLogger(GettingStartedDefaultScenario.class); + + /* known software module type name and key */ + private static final String SM_MODULE_TYPE = "gettingstarted"; + + /* known distribution set type name and key */ + private static final String DS_MODULE_TYPE = "gettingstarted"; + + /* known distribution name of this getting started example */ + private static final String SM_EXAMPLE_NAME = "gettingstarted-example"; + + /* known distribution name of this getting started example */ + private static final String DS_EXAMPLE_NAME = "gettingstarted-example"; + + @Autowired + private DistributionSetResourceClient distributionSetResource; + + @Autowired + private DistributionSetTypeResourceClient distributionSetTypeResource; + + @Autowired + private SoftwareModuleResourceClient softwareModuleResource; + + @Autowired + private SoftwareModuleTypeResourceClient softwareModuleTypeResource; + + /** + * Run the default getting started scenario. + */ + public void run() { + + LOGGER.info("Running Getting-Started-Scenario..."); + + // create one SoftwareModuleTypes + LOGGER.info("Creating software module type {}", SM_MODULE_TYPE); + final SoftwareModuleTypesRest createdSoftwareModuleTypes = softwareModuleTypeResource.createSoftwareModuleTypes( + new SoftwareModuleTypeBuilder().key(SM_MODULE_TYPE).name(SM_MODULE_TYPE).maxAssignments(1).build()) + .getBody(); + + // create one DistributionSetType + LOGGER.info("Creating distribution set type {}", DS_MODULE_TYPE); + distributionSetTypeResource.createDistributionSetTypes(new DistributionSetTypeBuilder().key(DS_MODULE_TYPE) + .name(DS_MODULE_TYPE).mandatorymodules(createdSoftwareModuleTypes.get(0).getModuleId()).build()); + + // create three DistributionSet + final String dsVersion1 = "1.0.0"; + final String dsVersion2 = "2.0.0"; + final String dsVersion3 = "2.1.0"; + + LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion1); + final DistributionSetsRest distributionSetsRest1 = distributionSetResource.createDistributionSets( + new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion1).type(DS_MODULE_TYPE).build()) + .getBody(); + + LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion2); + final DistributionSetsRest distributionSetsRest2 = distributionSetResource.createDistributionSets( + new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion2).type(DS_MODULE_TYPE).build()) + .getBody(); + + LOGGER.info("Creating distribution set {}:{}", DS_EXAMPLE_NAME, dsVersion3); + final DistributionSetsRest distributionSetsRest3 = distributionSetResource.createDistributionSets( + new DistributionSetBuilder().name(DS_EXAMPLE_NAME).version(dsVersion3).type(DS_MODULE_TYPE).build()) + .getBody(); + + // create three SoftwareModules + final String swVersion1 = "1"; + final String swVersion2 = "2"; + final String swVersion3 = "3"; + + LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion1); + final SoftwareModulesRest softwareModulesRest1 = softwareModuleResource.createSoftwareModules( + new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion1).type(SM_MODULE_TYPE).build()) + .getBody(); + LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion2); + final SoftwareModulesRest softwareModulesRest2 = softwareModuleResource.createSoftwareModules( + new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion2).type(SM_MODULE_TYPE).build()) + .getBody(); + LOGGER.info("Creating distribution set {}:{}", SM_EXAMPLE_NAME, swVersion3); + final SoftwareModulesRest softwareModulesRest3 = softwareModuleResource.createSoftwareModules( + new SoftwareModuleBuilder().name(SM_EXAMPLE_NAME).version(swVersion3).type(SM_MODULE_TYPE).build()) + .getBody(); + + // Assign SoftwareModules to DistributionSet + LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion1, + DS_EXAMPLE_NAME, dsVersion1); + distributionSetResource.assignSoftwareModules(distributionSetsRest1.get(0).getDsId(), + new SoftwareModuleAssigmentBuilder().id(softwareModulesRest1.get(0).getModuleId()).build()); + + LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion2, + DS_EXAMPLE_NAME, dsVersion2); + distributionSetResource.assignSoftwareModules(distributionSetsRest2.get(0).getDsId(), + new SoftwareModuleAssigmentBuilder().id(softwareModulesRest2.get(0).getModuleId()).build()); + + LOGGER.info("Assign software module {}:{} to distribution set {}:{}", SM_EXAMPLE_NAME, swVersion3, + DS_EXAMPLE_NAME, dsVersion3); + distributionSetResource.assignSoftwareModules(distributionSetsRest3.get(0).getDsId(), + new SoftwareModuleAssigmentBuilder().id(softwareModulesRest3.get(0).getModuleId()).build()); + } +} diff --git a/examples/hawkbit-mgmt-api-client/src/main/resources/application.properties b/examples/hawkbit-mgmt-api-client/src/main/resources/application.properties new file mode 100644 index 000000000..93eb7e982 --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/resources/application.properties @@ -0,0 +1,6 @@ +logging.level=trace +hawkbit.url=localhost:8080 +hawkbit.username=admin +hawkbit.password=admin + +spring.main.banner-mode=OFF \ No newline at end of file diff --git a/examples/hawkbit-mgmt-api-client/src/main/resources/logback.xml b/examples/hawkbit-mgmt-api-client/src/main/resources/logback.xml new file mode 100644 index 000000000..1c76f642a --- /dev/null +++ b/examples/hawkbit-mgmt-api-client/src/main/resources/logback.xml @@ -0,0 +1,20 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/DistributionSetTagTest.java b/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/DistributionSetTagTest.java deleted file mode 100644 index 17384c211..000000000 --- a/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/DistributionSetTagTest.java +++ /dev/null @@ -1,186 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import static org.fest.assertions.api.Assertions.assertThat; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.hawkbit.app.Start; -import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost; -import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest; -import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; -import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.annotation.Description; - -import ru.yandex.qatools.allure.annotations.Features; -import ru.yandex.qatools.allure.annotations.Stories; -import feign.Feign; -import feign.Logger; -import feign.auth.BasicAuthRequestInterceptor; -import feign.jackson.JacksonDecoder; -import feign.jackson.JacksonEncoder; - -@Features("Example Tests - Management RESTful API Client") -@Stories("DistrubutionSet Tag Resource") -public class DistributionSetTagTest { - - private DistrubutionSetTagResource distrubutionSetTagResource; - - private static List assignedTargetRequestBodies; - - @BeforeClass - public static void startupServer() { - SpringApplication.run(Start.class, new String[0]); - createTargetsAssignment(); - assignedTargetRequestBodies.add(new AssignedDistributionSetRequestBody().setDistributionSetId(100L)); - } - - @Before - public void setup() { - this.distrubutionSetTagResource = createDistrubutionSetTagResource(); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of distrubutionset tag by ID") - @Ignore - public void getDistributionSetTag() { - final TagsRest result = createDistributionSetTags(2); - - assertThat(distrubutionSetTagResource.getDistributionSetTag(result.get(0).getTagId()).getName()).isEqualTo( - "Tag0"); - - deleteDistributionSets(result); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple update of a distrubutionset tag") - @Ignore - public void updateDistributionSetTag() { - final TagsRest created = createDistributionSetTags(10); - - distrubutionSetTagResource.updateDistributionSetTag(created.get(0).getTagId(), new TagRequestBodyPut() - .setDescription("Test").setName("Test").setColour("Green")); - - final TagRest targetTag = distrubutionSetTagResource.getDistributionSetTag(created.get(0).getTagId()); - assertThat(targetTag.getName()).isEqualTo("Test"); - assertThat(targetTag.getDescription()).isEqualTo("Test"); - assertThat(targetTag.getColour()).isEqualTo("Green"); - - deleteDistributionSets(created); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of all assigned distrubutionsets by a distrubutionset tag.") - @Ignore - public void getDistributionSetByTagId() { - final TagsRest created = createDistributionSetTags(10); - distrubutionSetTagResource.assignDistributionSets(created.get(2).getTagId(), assignedTargetRequestBodies); - - final DistributionSetsRest distributionSetsRest = distrubutionSetTagResource - .getAssignedDistributionSets(created.get(2).getTagId()); - assertThat(distributionSetsRest).hasSize(5); - - distrubutionSetTagResource.unassignDistributionSets(created.get(2).getTagId()); - deleteDistributionSets(created); - } - - @Test - @Description("Toggle request to unassigned all assigned distrubutionset and assign all unassigned distrubutionset.") - @Ignore - public void toggleTagAssignment() { - final TagsRest created = createDistributionSetTags(10); - final Long id = created.get(2).getTagId(); - - distrubutionSetTagResource.assignDistributionSets(id, assignedTargetRequestBodies); - distrubutionSetTagResource.unassignDistributionSet(id, assignedTargetRequestBodies.get(0) - .getDistributionSetId()); - - DistributionSetTagAssigmentResultRest assigmentResultRest = distrubutionSetTagResource.toggleTagAssignment(id, - assignedTargetRequestBodies); - - final TagRest targetTag = distrubutionSetTagResource.getDistributionSetTag(created.get(2).getTagId()); - assertThat(assigmentResultRest.getAssignedDistributionSets()).hasSize(1); - assertThat(assigmentResultRest.getUnassignedDistributionSets()).hasSize(0); - - assigmentResultRest = distrubutionSetTagResource.toggleTagAssignment(id, assignedTargetRequestBodies); - assertThat(assigmentResultRest.getAssignedDistributionSets()).hasSize(0); - assertThat(assigmentResultRest.getUnassignedDistributionSets()).hasSize(5); - - distrubutionSetTagResource.unassignDistributionSets(targetTag.getTagId()); - deleteDistributionSets(created); - } - - private void deleteDistributionSets(final List tags) { - for (final TagRest tag : tags) { - distrubutionSetTagResource.deleteDistributionSetTag(tag.getTagId()); - } - } - - private TagsRest createDistributionSetTags(final int number) { - - final List tags = new ArrayList<>(); - for (int i = 0; i < number; i++) { - tags.add(new TagRequestBodyPut().setDescription("Tag " + i).setName("Tag" + i).setColour("Red")); - } - - final TagsRest result = distrubutionSetTagResource.createDistributionSetTags(tags); - - assertThat(result).hasSize(number); - return result; - } - - private DistrubutionSetTagResource createDistrubutionSetTagResource() { - final DistrubutionSetTagResource distrubutionSetTagResource = Feign.builder().logger(new Logger.ErrorLogger()) - .logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder()) - .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) - .target(DistrubutionSetTagResource.class, "http://localhost:8080"); - return distrubutionSetTagResource; - } - - private static void createTargetsAssignment() { - - final List sets = new ArrayList<>(); - assignedTargetRequestBodies = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - final DistributionSetRequestBodyPost bodyPost = (DistributionSetRequestBodyPost) new DistributionSetRequestBodyPost() - .setName("Ds" + i).setDescription("Ds" + i).setVersion("" + i); - sets.add(bodyPost); - } - - final DistributionSetsRest result = createDistributionSetResource().createDistributionSets(sets); - for (final DistributionSetRest rest : result) { - assignedTargetRequestBodies.add(new AssignedDistributionSetRequestBody().setDistributionSetId(rest - .getDsId())); - } - - } - - private static DistributionSetResource createDistributionSetResource() { - final DistributionSetResource distributionSetResource = Feign.builder().logger(new Logger.ErrorLogger()) - .logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder()) - .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) - .target(DistributionSetResource.class, "http://localhost:8080"); - return distributionSetResource; - } - -} diff --git a/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/TargetTagTest.java b/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/TargetTagTest.java deleted file mode 100644 index 10f18b704..000000000 --- a/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/TargetTagTest.java +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import static org.fest.assertions.api.Assertions.assertThat; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.hawkbit.app.Start; -import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; -import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; -import org.eclipse.hawkbit.rest.resource.model.tag.TargetTagAssigmentResultRest; -import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.target.TargetRest; -import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.annotation.Description; - -import ru.yandex.qatools.allure.annotations.Features; -import ru.yandex.qatools.allure.annotations.Stories; -import feign.Feign; -import feign.Logger; -import feign.auth.BasicAuthRequestInterceptor; -import feign.jackson.JacksonDecoder; -import feign.jackson.JacksonEncoder; - -@Features("Example Tests - Management RESTful API Client") -@Stories("Target Tag Resource") -public class TargetTagTest { - - private TargetTagResource targetTagResource; - - private static List assignedTargetRequestBodies; - - @BeforeClass - public static void startupServer() { - SpringApplication.run(Start.class, new String[0]); - createTargetsAssignment(); - assignedTargetRequestBodies.add(new AssignedTargetRequestBody().setControllerId("NotExist")); - } - - @Before - public void setup() { - this.targetTagResource = createTargetTagResource(); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of target tag by ID") - @Ignore - public void getTargetTag() { - final TagsRest result = createTargetTags(2); - - assertThat(targetTagResource.getTargetTag(result.get(0).getTagId()).getName()).isEqualTo("Tag0"); - - deleteTargets(result); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple update of a target tag") - @Ignore - public void updateTargetTag() { - final TagsRest created = createTargetTags(10); - - targetTagResource.updateTagretTag(created.get(0).getTagId(), new TagRequestBodyPut().setDescription("Test") - .setName("Test").setColour("Green")); - - final TagRest targetTag = targetTagResource.getTargetTag(created.get(0).getTagId()); - assertThat(targetTag.getName()).isEqualTo("Test"); - assertThat(targetTag.getDescription()).isEqualTo("Test"); - assertThat(targetTag.getColour()).isEqualTo("Green"); - - deleteTargets(created); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of all assigned targets by a target tag.") - @Ignore - public void getTargetsByTargetTagId() { - final TagsRest created = createTargetTags(10); - final Long tagId = created.get(2).getTagId(); - targetTagResource.assignTargets(tagId, assignedTargetRequestBodies); - - final TagRest targetTag = targetTagResource.getTargetTag(tagId); - assertThat(targetTagResource.getAssignedTargets(tagId)).hasSize(5); - - targetTagResource.unassignTargets(targetTag.getTagId()); - deleteTargets(created); - } - - @Test - @Description("Toggle request to unassigned all assigned targets and assign all unassigned targets.") - @Ignore - public void toggleTagAssignment() { - final TagsRest created = createTargetTags(10); - final Long id = created.get(2).getTagId(); - - targetTagResource.assignTargets(id, assignedTargetRequestBodies); - targetTagResource.unassignTarget(id, assignedTargetRequestBodies.get(0).getControllerId()); - - TargetTagAssigmentResultRest assigmentResultRest = targetTagResource.toggleTagAssignment(id, - assignedTargetRequestBodies); - - final TagRest targetTag = targetTagResource.getTargetTag(created.get(2).getTagId()); - assertThat(assigmentResultRest.getAssignedTargets()).hasSize(1); - assertThat(assigmentResultRest.getUnassignedTargets()).hasSize(0); - - assigmentResultRest = targetTagResource.toggleTagAssignment(id, assignedTargetRequestBodies); - assertThat(assigmentResultRest.getAssignedTargets()).hasSize(0); - assertThat(assigmentResultRest.getUnassignedTargets()).hasSize(5); - - targetTagResource.unassignTargets(targetTag.getTagId()); - deleteTargets(created); - } - - private void deleteTargets(final List tags) { - for (final TagRest tag : tags) { - targetTagResource.deleteTargetTag(tag.getTagId()); - } - } - - private TagsRest createTargetTags(final int number) { - - final List tags = new ArrayList<>(); - for (int i = 0; i < number; i++) { - tags.add(new TagRequestBodyPut().setDescription("Tag " + i).setName("Tag" + i).setColour("Red")); - } - - final TagsRest result = targetTagResource.createTargetTag(tags); - - assertThat(result).hasSize(number); - return result; - } - - private TargetTagResource createTargetTagResource() { - final TargetTagResource targetResource = Feign.builder().logger(new Logger.ErrorLogger()) - .logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder()) - .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) - .target(TargetTagResource.class, "http://localhost:8080"); - return targetResource; - } - - private static void createTargetsAssignment() { - - final List targets = new ArrayList<>(); - assignedTargetRequestBodies = new ArrayList<>(); - for (int i = 0; i < 5; i++) { - - targets.add(new TargetRequestBody().setControllerId("test" + i).setName("testDevice")); - } - - final TargetsRest result = createTargetResource().createTargets(targets); - for (final TargetRest rest : result) { - assignedTargetRequestBodies.add(new AssignedTargetRequestBody().setControllerId(rest.getControllerId())); - } - - } - - private static TargetResource createTargetResource() { - final TargetResource targetResource = Feign.builder().logger(new Logger.ErrorLogger()) - .logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder()) - .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) - .target(TargetResource.class, "http://localhost:8080"); - return targetResource; - } - -} diff --git a/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/TargetTest.java b/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/TargetTest.java deleted file mode 100644 index 745b119f6..000000000 --- a/examples/hawkbit-mgmt-api-client/src/test/java/org/eclipse/hawkbit/mgmt/api/client/TargetTest.java +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.mgmt.api.client; - -import static org.fest.assertions.api.Assertions.assertThat; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.hawkbit.app.Start; -import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList; -import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody; -import org.eclipse.hawkbit.rest.resource.model.target.TargetRest; -import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.springframework.boot.SpringApplication; -import org.springframework.context.annotation.Description; - -import feign.Feign; -import feign.Logger; -import feign.auth.BasicAuthRequestInterceptor; -import feign.jackson.JacksonDecoder; -import feign.jackson.JacksonEncoder; -import ru.yandex.qatools.allure.annotations.Features; -import ru.yandex.qatools.allure.annotations.Stories; - -@Features("Example Tests - Management RESTful API Client") -@Stories("Target Resource") -public class TargetTest { - - @BeforeClass - public static void startupServer() { - SpringApplication.run(Start.class, new String[0]); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of target by ID") - @Ignore - public void getTarget() { - final TargetResource targetResource = createTargetResource(); - final TargetsRest result = createTargets(targetResource, 1); - - assertThat(targetResource.getTarget("test0").getName()).isEqualTo("testDevice"); - - deleteTargets(targetResource, result); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of all targets with defined page sizing information (i.e. offset and limit).") - @Ignore - public void getTargetsAsPagedListWithDefinedPageSizing() { - final TargetResource targetResource = createTargetResource(); - final TargetsRest created = createTargets(targetResource, 20); - - final TargetPagedList queryResult = targetResource.getTargets(0, 10); - - assertThat(queryResult.getContent()).hasSize(10); - assertThat(queryResult.getTotal()).isEqualTo(20); - assertThat(queryResult.getSize()).isEqualTo(10); - - deleteTargets(targetResource, created); - } - - // disabled as this runs not on CI environments. - @Test - @Description("Simple request of all targets with defualt paging parameters.") - @Ignore - public void getTargetsAsPagedListWithDefaultPageSizing() { - final TargetResource targetResource = createTargetResource(); - final TargetsRest created = createTargets(targetResource, 20); - - final TargetPagedList queryResult = targetResource.getTargets(); - - assertThat(queryResult.getContent()).hasSize(20); - assertThat(queryResult.getTotal()).isEqualTo(20); - assertThat(queryResult.getSize()).isEqualTo(20); - - deleteTargets(targetResource, created); - } - - private void deleteTargets(final TargetResource targetResource, final List targets) { - for (final TargetRest targetRest : targets) { - targetResource.deleteTarget(targetRest.getControllerId()); - } - } - - private TargetsRest createTargets(final TargetResource targetResource, final int number) { - - final List targets = new ArrayList<>(); - for (int i = 0; i < number; i++) { - - targets.add(new TargetRequestBody().setControllerId("test" + i).setName("testDevice")); - } - - final TargetsRest result = targetResource.createTargets(targets); - - assertThat(result).hasSize(number); - return result; - } - - private TargetResource createTargetResource() { - final TargetResource targetResource = Feign.builder().logger(new Logger.ErrorLogger()) - .logLevel(Logger.Level.BASIC).decoder(new JacksonDecoder()).encoder(new JacksonEncoder()) - .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) - .target(TargetResource.class, "http://localhost:8080"); - return targetResource; - } - -} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetRestApi.java new file mode 100644 index 000000000..05d377950 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetRestApi.java @@ -0,0 +1,365 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ + +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.MetadataRest; +import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetPagedList; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; +import org.eclipse.hawkbit.rest.resource.model.distributionset.TargetAssignmentRequestBody; +import org.eclipse.hawkbit.rest.resource.model.distributionset.TargetAssignmentResponseBody; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleAssigmentRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulePagedList; +import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * REST Resource handling for DistributionSet CRUD operations. + */ +@RequestMapping(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) +public interface DistributionSetRestApi { + + /** + * Handles the GET request of retrieving all DistributionSets . + * + * @param pagingOffsetParam + * the offset of list of sets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a list of all set for a defined or default page request with + * status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getDistributionSets( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single DistributionSet . + * + * @param distributionSetId + * the ID of the set to retrieve + * + * @return a single DistributionSet with status OK. + * + * @throws EntityNotFoundException + * in case no DistributionSet with the given ID exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getDistributionSet( + @PathVariable("distributionSetId") final Long distributionSetId); + + /** + * Handles the POST request of creating new distribution sets . The request + * body must always be a list of sets. + * + * @param sets + * the DistributionSets to be created. + * @return In case all sets could successful created the ResponseEntity with + * status code 201 - Created but without ResponseBody. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, + "application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createDistributionSets( + @RequestBody final List sets); + + /** + * Handles the DELETE request for a single DistributionSet . + * + * @param distributionSetId + * the ID of the DistributionSet to delete + * @return status OK if delete as successful. + * + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}") + public ResponseEntity deleteDistributionSet(@PathVariable("distributionSetId") final Long distributionSetId); + + /** + * Handles the UPDATE request for a single DistributionSet . + * + * @param distributionSetId + * the ID of the DistributionSet to delete + * @param toUpdate + * with the data that needs updating + * + * @return status OK if update as successful with updated content. + * + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity updateDistributionSet( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestBody final DistributionSetRequestBodyPut toUpdate); + + /** + * Handles the GET request of retrieving assigned targets to a specific + * distribution set. + * + * @param distributionSetId + * the ID of the distribution set to retrieve the assigned + * targets + * @param pagingOffsetParam + * the offset of list of targets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return status OK if get request is successful with the paged list of + * targets + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedTargets", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getAssignedTargets( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving installed targets to a specific + * distribution set. + * + * @param distributionSetId + * the ID of the distribution set to retrieve the assigned + * targets + * @param pagingOffsetParam + * the offset of list of targets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return status OK if get request is successful with the paged list of + * targets + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/installedTargets", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getInstalledTargets( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the POST request of assigning multiple targets to a single + * distribution set. + * + * @param distributionSetId + * the ID of the distribution set within the URL path parameter + * @param targetIds + * the IDs of the target which should get assigned to the + * distribution set given in the response body + * @return status OK if the assignment of the targets was successful and a + * complex return body which contains information about the assigned + * targets and the already assigned targets counters + */ + @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedTargets", consumes = { + "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity createAssignedTarget( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestBody final List targetIds); + + /** + * Gets a paged list of meta data for a distribution set. + * + * @param distributionSetId + * the ID of the distribution set for the meta data + * @param pagingOffsetParam + * the offset of list of targets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=key==abc} + * @return status OK if get request is successful with the paged list of + * meta data + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getMetadata( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Gets a single meta data value for a specific key of a distribution set. + * + * @param distributionSetId + * the ID of the distribution set to get the meta data from + * @param metadataKey + * the key of the meta data entry to retrieve the value from + * @return status OK if get request is successful with the value of the meta + * data + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata/{metadataKey}", produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getMetadataValue( + @PathVariable("distributionSetId") final Long distributionSetId, + @PathVariable("metadataKey") final String metadataKey); + + /** + * Updates a single meta data value of a distribution set. + * + * @param distributionSetId + * the ID of the distribution set to update the meta data entry + * @param metadataKey + * the key of the meta data to update the value + * @return status OK if the update request is successful and the updated + * meta data result + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}/metadata/{metadataKey}", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity updateMetadata(@PathVariable("distributionSetId") final Long distributionSetId, + @PathVariable("metadataKey") final String metadataKey, @RequestBody final MetadataRest metadata); + + /** + * Deletes a single meta data entry from the distribution set. + * + * @param distributionSetId + * the ID of the distribution set to delete the meta data entry + * @param metadataKey + * the key of the meta data to delete + * @return status OK if the delete request is successful + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/metadata/{metadataKey}") + public ResponseEntity deleteMetadata(@PathVariable("distributionSetId") final Long distributionSetId, + @PathVariable("metadataKey") final String metadataKey); + + /** + * Creates a list of meta data for a specific distribution set. + * + * @param distributionSetId + * the ID of the distribution set to create meta data for + * @param metadataRest + * the list of meta data entries to create + * @return status created if post request is successful with the value of + * the created meta data + */ + @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/metadata", consumes = { + MediaType.APPLICATION_JSON_VALUE, + "application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity> createMetadata( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestBody final List metadataRest); + + /** + * Assigns a list of software modules to a distribution set. + * + * @param distributionSetId + * the ID of the distribution set to assign software modules for + * @param softwareModuleIDs + * the list of software modules ids to assign + * @return http status + * + * @throws EntityNotFoundException + * in case no distribution set with the given + * {@code distributionSetId} exists. + */ + @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedSM", consumes = { + MediaType.APPLICATION_JSON_VALUE, + "application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity assignSoftwareModules(@PathVariable("distributionSetId") final Long distributionSetId, + @RequestBody final List softwareModuleIDs); + + /** + * Deletes the assignment of the software module form the distribution set. + * + * @param distributionSetId + * the ID of the distribution set to reject the software module + * for + * @param softwareModuleId + * the software module id to get rejected form the distribution + * set + * @return status OK if rejection was successful. + * @throws EntityNotFoundException + * in case no distribution set with the given + * {@code distributionSetId} exists. + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/assignedSM/{softwareModuleId}") + public ResponseEntity deleteAssignSoftwareModules( + @PathVariable("distributionSetId") final Long distributionSetId, + @PathVariable("softwareModuleId") final Long softwareModuleId); + + /** + * Handles the GET request for retrieving the assigned software modules of a + * specific distribution set. + * + * @param distributionSetId + * the ID of the distribution to retrieve + * @param pagingOffsetParam + * the offset of list of sets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @return a list of the assigned software modules of a distribution set + * with status OK, if none is assigned than {@code null} + * @throws EntityNotFoundException + * in case no distribution set with the given + * {@code distributionSetId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedSM", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getAssignedSoftwareModules( + @PathVariable("distributionSetId") final Long distributionSetId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam); +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetTagRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetTagRestApi.java new file mode 100644 index 000000000..d99368dc2 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetTagRestApi.java @@ -0,0 +1,215 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; +import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody; +import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest; +import org.eclipse.hawkbit.rest.resource.model.tag.TagPagedList; +import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; +import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * REST Resource handling for DistributionSetTag CRUD operations. + * + */ +@RequestMapping(RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) +public interface DistributionSetTagRestApi { + /** + * Handles the GET request of retrieving all DistributionSet tags. + * + * @param pagingOffsetParam + * the offset of list of DistributionSet tags for pagination, + * might not be present in the rest request then default value + * will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a list of all target tags for a defined or default page request + * with status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getDistributionSetTags( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single distribution set tag. + * + * @param distributionsetTagId + * the ID of the distribution set tag to retrieve + * + * @return a single distribution set tag with status OK. + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionsetTagId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getDistributionSetTag( + @PathVariable("distributionsetTagId") final Long distributionsetTagId); + + /** + * Handles the POST request of creating new distribution set tag. The + * request body must always be a list of tags. + * + * @param tags + * the distribution set tags to be created. + * @return In case all modules could successful created the ResponseEntity + * with status code 201 - Created. The Response Body are the created + * distribution set tags but without ResponseBody. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createDistributionSetTags(@RequestBody final List tags); + + /** + * + * Handles the PUT request of updating a single distribution set tag. + * + * @param distributionsetTagId + * the ID of the distribution set tag + * @param restDSTagRest + * the the request body to be updated + * @return status OK if update is successful and the updated distribution + * set tag. + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{distributionsetTagId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateDistributionSetTag( + @PathVariable("distributionsetTagId") final Long distributionsetTagId, + @RequestBody final TagRequestBodyPut restDSTagRest); + + /** + * Handles the DELETE request for a single distribution set tag. + * + * @param distributionsetTagId + * the ID of the distribution set tag + * @return status OK if delete as successfully. + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + * + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionsetTagId}") + public ResponseEntity deleteDistributionSetTag( + @PathVariable("distributionsetTagId") final Long distributionsetTagId); + + /** + * Handles the GET request of retrieving all assigned distribution sets by + * the given tag id. + * + * @param distributionsetTagId + * the ID of the distribution set tag + * + * @return the list of assigned distribution sets. + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.GET, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) + public ResponseEntity getAssignedDistributionSets( + @PathVariable("distributionsetTagId") final Long distributionsetTagId); + + /** + * Handles the POST request to toggle the assignment of distribution sets by + * the given tag id. + * + * @param distributionsetTagIds + * the ID of the distribution set tag to retrieve + * @param assignedDSRequestBodies + * list of distribution set ids to be toggled + * + * @return the list of assigned distribution sets and unassigned + * distribution sets. + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING + + "/toggleTagAssignment") + public ResponseEntity toggleTagAssignment( + @PathVariable("distributionsetTagId") final Long distributionsetTagId, + @RequestBody final List assignedDSRequestBodies); + + /** + * Handles the POST request to assign distribution sets to the given tag id. + * + * @param distributionsetTagId + * the ID of the distribution set tag to retrieve + * @param assignedDSRequestBodies + * list of distribution sets ids to be assigned + * + * @return the list of assigned distribution set. + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) + public ResponseEntity assignDistributionSets( + @PathVariable("distributionsetTagId") final Long distributionsetTagId, + @RequestBody final List assignedDSRequestBodies); + + /** + * Handles the DELETE request to unassign all distribution set from the + * given tag id. + * + * @param distributionsetTagId + * the ID of the distribution set tag to retrieve + * @return http status code + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) + public ResponseEntity unassignDistributionSets( + @PathVariable("distributionsetTagId") final Long distributionsetTagId); + + /** + * Handles the DELETE request to unassign one distribution set from the + * given tag id. + * + * @param distributionsetTagId + * the ID of the distribution set tag + * @param distributionsetId + * the ID of the distribution set to unassign + * @return http status code + * @throws EntityNotFoundException + * in case the given {@code distributionsetTagId} doesn't + * exists. + */ + @RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING + + "/{distributionsetId}") + public ResponseEntity unassignDistributionSet( + @PathVariable("distributionsetTagId") final Long distributionsetTagId, + @PathVariable("distributionsetId") final Long distributionsetId); +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetTypeRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetTypeRestApi.java new file mode 100644 index 000000000..9bed7f4f8 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/DistributionSetTypeRestApi.java @@ -0,0 +1,259 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.IdRest; +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypePagedList; +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRest; +import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypesRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * REST Resource handling for SoftwareModule and related Artifact CRUD + * operations. + * + */ +@RequestMapping(RestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) +public interface DistributionSetTypeRestApi { + + /** + * Handles the GET request of retrieving all DistributionSetTypes. + * + * @param pagingOffsetParam + * the offset of list of modules for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * + * @return a list of all DistributionSetType for a defined or default page + * request with status OK. The response is always paged. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getDistributionSetTypes( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single DistributionSetType + * within. + * + * @param distributionSetTypeId + * the ID of the module type to retrieve + * + * @return a single softwareModule with status OK. + * @throws EntityNotFoundException + * in case no with the given {@code softwareModuleId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getDistributionSetType( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId); + + /** + * Handles the DELETE request for a single Distribution Set Type. + * + * @param distributionSetTypeId + * the ID of the module to retrieve + * @return status OK if delete as sucessfull. + * + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}") + public ResponseEntity deleteDistributionSetType( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId); + + /** + * Handles the PUT request of updating a Distribution Set Type. + * + * @param distributionSetTypeId + * the ID of the software module in the URL + * @param restDistributionSetType + * the module type to be updated. + * @return status OK if update is successful + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetTypeId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateDistributionSetType( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, + @RequestBody final DistributionSetTypeRequestBodyPut restDistributionSetType); + + /** + * Handles the POST request of creating new DistributionSetTypes. The + * request body must always be a list of types. + * + * @param distributionSetTypes + * the modules to be created. + * @return In case all modules could successful created the ResponseEntity + * with status code 201 - Created but without ResponseBody. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createDistributionSetTypes( + @RequestBody final List distributionSetTypes); + + /** + * Handles the GET request of retrieving the list of mandatory software + * module types in that distribution set type. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @return Unpaged list of module types and OK in case of success. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getMandatoryModules( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId); + + /** + * Handles the GET request of retrieving the single mandatory software + * module type in that distribution set type. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @param softwareModuleTypeId + * of SoftwareModuleType. + * @return Unpaged list of module types and OK in case of success. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES + + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getMandatoryModule( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId); + + /** + * Handles the GET request of retrieving the single optional software module + * type in that distribution set type. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @param softwareModuleTypeId + * of SoftwareModuleType. + * @return Unpaged list of module types and OK in case of success. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES + + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getOptionalModule( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId); + + /** + * Handles the GET request of retrieving the list of optional software + * module types in that distribution set type. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @return Unpaged list of module types and OK in case of success. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getOptionalModules( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId); + + /** + * Handles DELETE request for removing a mandatory module from the + * DistributionSetType. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @param softwareModuleTypeId + * of the SoftwareModuleType to remove + * + * @return OK if the request was successful + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES + + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity removeMandatoryModule( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId); + + /** + * Handles DELETE request for removing an optional module from the + * DistributionSetType. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @param softwareModuleTypeId + * of the SoftwareModuleType to remove + * + * @return OK if the request was successful + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES + + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity removeOptionalModule( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId); + + /** + * Handles the POST request for adding a mandatory software module type to a + * distribution set type. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @param smtId + * of the SoftwareModuleType to add + * + * @return OK if the request was successful + */ + @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity addMandatoryModule( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final IdRest smtId); + + /** + * Handles the POST request for adding an optional software module type to a + * distribution set type. + * + * @param distributionSetTypeId + * of the DistributionSetType. + * @param smtId + * of the SoftwareModuleType to add + * + * @return OK if the request was successful + */ + @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/" + + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity addOptionalModule( + @PathVariable("distributionSetTypeId") final Long distributionSetTypeId, @RequestBody final IdRest smtId); + +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/RolloutRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/RolloutRestApi.java new file mode 100644 index 000000000..fe1c7caa5 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/RolloutRestApi.java @@ -0,0 +1,209 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutPagedList; +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutResponseBody; +import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody; +import org.eclipse.hawkbit.rest.resource.model.rolloutgroup.RolloutGroupPagedList; +import org.eclipse.hawkbit.rest.resource.model.rolloutgroup.RolloutGroupResponseBody; +import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * REST Resource handling rollout CRUD operations. + * + */ +@RequestMapping(RestConstants.ROLLOUT_V1_REQUEST_MAPPING) +public interface RolloutRestApi { + + /** + * Handles the GET request of retrieving all rollouts. + * + * @param pagingOffsetParam + * the offset of list of rollouts for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a list of all rollouts for a defined or default page request with + * status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getRollouts( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single rollout. + * + * @param rolloutId + * the ID of the rollout to retrieve + * @return a single rollout with status OK. + * @throws EntityNotFoundException + * in case no rollout with the given {@code rolloutId} exists. + */ + @RequestMapping(value = "/{rolloutId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, + "application/hal+json" }) + public ResponseEntity getRollout(@PathVariable("rolloutId") final Long rolloutId); + + /** + * Handles the POST request for creating rollout. + * + * @param rollout + * the rollout body to be created. + * @return In case rollout could successful created the ResponseEntity with + * status code 201 with the successfully created rollout. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + * @throws EntityNotFoundException + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity create(@RequestBody final RolloutRestRequestBody rolloutRequestBody); + + /** + * Handles the POST request for starting a rollout. + * + * @param rolloutId + * the ID of the rollout to be started. + * @return OK response (200) if rollout could be started. In case of any + * exception the corresponding errors occur. + * @throws EntityNotFoundException + * @see RolloutManagement#startRollout(Rollout) + * @see ResponseExceptionHandler + */ + @RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/start", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity start(@PathVariable("rolloutId") final Long rolloutId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_ASYNC, defaultValue = "false") final boolean startAsync); + + /** + * Handles the POST request for pausing a rollout. + * + * @param rolloutId + * the ID of the rollout to be paused. + * @return OK response (200) if rollout could be paused. In case of any + * exception the corresponding errors occur. + * @throws EntityNotFoundException + * @see RolloutManagement#pauseRollout(Rollout) + * @see ResponseExceptionHandler + */ + @RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/pause", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity pause(@PathVariable("rolloutId") final Long rolloutId); + + /** + * Handles the POST request for resuming a rollout. + * + * @param rolloutId + * the ID of the rollout to be resumed. + * @return OK response (200) if rollout could be resumed. In case of any + * exception the corresponding errors occur. + * @throws EntityNotFoundException + * @see RolloutManagement#resumeRollout(Rollout) + * @see ResponseExceptionHandler + */ + @RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/resume", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity resume(@PathVariable("rolloutId") final Long rolloutId); + + /** + * Handles the GET request of retrieving all rollout groups referred to a + * rollout. + * + * @param pagingOffsetParam + * the offset of list of rollout groups for pagination, might not + * be present in the rest request then default value will be + * applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a list of all rollout groups referred to a rollout for a defined + * or default page request with status OK. The response is always + * paged. In any failure the JsonResponseExceptionHandler is + * handling the response. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getRolloutGroups(@PathVariable("rolloutId") final Long rolloutId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request for retrieving a single rollout group. + * + * @param rolloutId + * the rolloutId to retrieve the group from + * @param groupId + * the groupId to retrieve the rollout group + * @return the OK response containing the RolloutGroupResponseBody + * @throws EntityNotFoundException + */ + @RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getRolloutGroup(@PathVariable("rolloutId") final Long rolloutId, + @PathVariable("groupId") final Long groupId); + + /** + * Retrieves all targets related to a specific rollout group. + * + * @param rolloutId + * the ID of the rollout + * @param groupId + * the ID of the rollout group + * @param pagingOffsetParam + * the offset of list of rollout groups for pagination, might not + * be present in the rest request then default value will be + * applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a paged list of targets related to a specific rollout and rollout + * group. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}/targets", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId, + @PathVariable("groupId") final Long groupId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/SoftwareModuleRestAPI.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/SoftwareModuleRestAPI.java new file mode 100644 index 000000000..0662c43ba --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/SoftwareModuleRestAPI.java @@ -0,0 +1,289 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.MetadataRest; +import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList; +import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest; +import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactsRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulePagedList; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModuleRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremodule.SoftwareModulesRest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; + +/** + * REST Resource handling for SoftwareModule and related Artifact CRUD + * operations. + * + */ +@RequestMapping(RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) +public interface SoftwareModuleRestAPI { + + /** + * Handles POST request for artifact upload. + * + * @param softwareModuleId + * of the parent SoftwareModule + * @param file + * that has to be uploaded + * @param optionalFileName + * to override {@link MultipartFile#getOriginalFilename()} + * @param md5Sum + * checksum for uploaded content check + * @param sha1Sum + * checksum for uploaded content check + * + * @return In case all sets could successful be created the ResponseEntity + * with status code 201 - Created but without ResponseBody. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/artifacts", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity uploadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, + @RequestParam("file") final MultipartFile file, + @RequestParam(value = "filename", required = false) final String optionalFileName, + @RequestParam(value = "md5sum", required = false) final String md5Sum, + @RequestParam(value = "sha1sum", required = false) final String sha1Sum); + + /** + * Handles the GET request of retrieving all meta data of artifacts assigned + * to a software module. + * + * @param softwareModuleId + * of the parent SoftwareModule + * + * @return a list of all artifacts for a defined or default page request + * with status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @ResponseBody + public ResponseEntity getArtifacts(@PathVariable("softwareModuleId") final Long softwareModuleId); + + /** + * Handles the GET request of retrieving a single Artifact meta data + * request. + * + * @param softwareModuleId + * of the parent SoftwareModule + * @param artifactId + * of the related LocalArtifact + * + * @return responseEntity with status ok if successful + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @ResponseBody + public ResponseEntity getArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, + @PathVariable("artifactId") final Long artifactId); + + /** + * Handles the DELETE request for a single SoftwareModule. + * + * @param softwareModuleId + * the ID of the module that has the artifact + * @param artifactId + * of the artifact to be deleted + * + * @return status OK if delete as successful. + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/artifacts/{artifactId}") + @ResponseBody + public ResponseEntity deleteArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, + @PathVariable("artifactId") final Long artifactId); + + /** + * Handles the GET request of retrieving all softwaremodules. + * + * @param pagingOffsetParam + * the offset of list of modules for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * + * @return a list of all modules for a defined or default page request with + * status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getSoftwareModules( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single software module. + * + * @param softwareModuleId + * the ID of the module to retrieve + * + * @return a single softwareModule with status OK. + * @throws EntityNotFoundException + * in case no with the given {@code softwareModuleId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getSoftwareModule( + @PathVariable("softwareModuleId") final Long softwareModuleId); + + /** + * Handles the POST request of creating new softwaremodules. The request + * body must always be a list of modules. + * + * @param softwareModules + * the modules to be created. + * @return In case all modules could successful created the ResponseEntity + * with status code 201 - Created but without ResponseBody. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createSoftwareModules( + @RequestBody final List softwareModules); + + /** + * Handles the PUT request of updating a software module. + * + * @param softwareModuleId + * the ID of the software module in the URL + * @param restSoftwareModule + * the modules to be updated. + * @return status OK if update is successful + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateSoftwareModule( + @PathVariable("softwareModuleId") final Long softwareModuleId, + @RequestBody final SoftwareModuleRequestBodyPut restSoftwareModule); + + /** + * Handles the DELETE request for a single softwaremodule. + * + * @param softwareModuleId + * the ID of the module to retrieve + * @return status OK if delete as sucessfull. + * + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}") + public ResponseEntity deleteSoftwareModule(@PathVariable("softwareModuleId") final Long softwareModuleId); + + /** + * Gets a paged list of meta data for a software module. + * + * @param softwareModuleId + * the ID of the software module for the meta data + * @param pagingOffsetParam + * the offset of list of meta data for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=key==abc} + * @return status OK if get request is successful with the paged list of + * meta data + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity getMetadata( + @PathVariable("softwareModuleId") final Long softwareModuleId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Gets a single meta data value for a specific key of a software module. + * + * @param softwareModuleId + * the ID of the software module to get the meta data from + * @param metadataKey + * the key of the meta data entry to retrieve the value from + * @return status OK if get request is successful with the value of the meta + * data + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = { + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getMetadataValue(@PathVariable("softwareModuleId") final Long softwareModuleId, + @PathVariable("metadataKey") final String metadataKey); + + /** + * Updates a single meta data value of a software module. + * + * @param softwareModuleId + * the ID of the software module to update the meta data entry + * @param metadataKey + * the key of the meta data to update the value + * @return status OK if the update request is successful and the updated + * meta data result + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = { + MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity updateMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId, + @PathVariable("metadataKey") final String metadataKey, @RequestBody final MetadataRest metadata); + + /** + * Deletes a single meta data entry from the software module. + * + * @param softwareModuleId + * the ID of the software module to delete the meta data entry + * @param metadataKey + * the key of the meta data to delete + * @return status OK if the delete request is successful + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/metadata/{metadataKey}") + public ResponseEntity deleteMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId, + @PathVariable("metadataKey") final String metadataKey); + + /** + * Creates a list of meta data for a specific software module. + * + * @param softwareModuleId + * the ID of the distribution set to create meta data for + * @param metadataRest + * the list of meta data entries to create + * @return status created if post request is successful with the value of + * the created meta data + */ + @RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/metadata", consumes = { + MediaType.APPLICATION_JSON_VALUE, + "application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + public ResponseEntity> createMetadata( + @PathVariable("softwareModuleId") final Long softwareModuleId, + @RequestBody final List metadataRest); + +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/SoftwareModuleTypeRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/SoftwareModuleTypeRestApi.java new file mode 100644 index 000000000..0c4756a04 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/SoftwareModuleTypeRestApi.java @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypePagedList; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRest; +import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * REST Resource handling for SoftwareModule and related Artifact CRUD + * operations. + * + */ +@RequestMapping(RestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) +public interface SoftwareModuleTypeRestApi { + /** + * Handles the GET request of retrieving all SoftwareModuleTypes . + * + * @param pagingOffsetParam + * the offset of list of modules for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * + * @return a list of all module type for a defined or default page request + * with status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getTypes( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single software module type . + * + * @param softwareModuleTypeId + * the ID of the module type to retrieve + * + * @return a single softwareModule with status OK. + * @throws EntityNotFoundException + * in case no with the given {@code softwareModuleId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleTypeId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getSoftwareModuleType( + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId); + + /** + * Handles the DELETE request for a single software module type . + * + * @param softwareModuleTypeId + * the ID of the module to retrieve + * @return status OK if delete as successfully. + * + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleTypeId}") + public ResponseEntity deleteSoftwareModuleType( + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId); + + /** + * Handles the PUT request of updating a software module type . + * + * @param softwareModuleTypeId + * the ID of the software module in the URL + * @param restSoftwareModuleType + * the module type to be updated. + * @return status OK if update is successful + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleTypeId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateSoftwareModuleType( + @PathVariable("softwareModuleTypeId") final Long softwareModuleTypeId, + @RequestBody final SoftwareModuleTypeRequestBodyPut restSoftwareModuleType); + + /** + * Handles the POST request of creating new SoftwareModuleTypes. The request + * body must always be a list of types. + * + * @param softwareModuleTypes + * the modules to be created. + * @return In case all modules could successful created the ResponseEntity + * with status code 201 - Created but without ResponseBody. In any + * failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createSoftwareModuleTypes( + @RequestBody final List softwareModuleTypes); + +} diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/TargetRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/TargetRestApi.java new file mode 100644 index 000000000..9d63a520f --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/TargetRestApi.java @@ -0,0 +1,284 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.action.ActionPagedList; +import org.eclipse.hawkbit.rest.resource.model.action.ActionRest; +import org.eclipse.hawkbit.rest.resource.model.action.ActionStatusPagedList; +import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest; +import org.eclipse.hawkbit.rest.resource.model.target.DistributionSetAssigmentRest; +import org.eclipse.hawkbit.rest.resource.model.target.TargetAttributes; +import org.eclipse.hawkbit.rest.resource.model.target.TargetPagedList; +import org.eclipse.hawkbit.rest.resource.model.target.TargetRequestBody; +import org.eclipse.hawkbit.rest.resource.model.target.TargetRest; +import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * Api for handling target operations. + */ +@RequestMapping(RestConstants.TARGET_V1_REQUEST_MAPPING) +public interface TargetRestApi { + + /** + * Handles the GET request of retrieving a single target. + * + * @param targetId + * the ID of the target to retrieve + * @return a single target with status OK. + * @throws EntityNotFoundException + * in case no target with the given {@code targetId} exists. + */ + + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getTarget(@PathVariable("targetId") final String targetId); + + /** + * Handles the GET request of retrieving all targets. + * + * @param pagingOffsetParam + * the offset of list of targets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a list of all targets for a defined or default page request with + * status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getTargets( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the POST request of creating new targets. The request body must + * always be a list of targets. + * + * @param targets + * the targets to be created. + * @return In case all targets could successful created the ResponseEntity + * with status code 201 with a list of successfully created + * entities. In any failure the JsonResponseExceptionHandler is + * handling the response. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createTargets(@RequestBody final List targets); + + /** + * Handles the PUT request of updating a target. The ID is within the URL + * path of the request. A given ID in the request body is ignored. It's not + * possible to set fields to {@code null} values. + * + * @param targetId + * the path parameter which contains the ID of the target + * @param targetRest + * the request body which contains the fields which should be + * updated, fields which are not given are ignored for the + * udpate. + * @return the updated target response which contains all fields also fields + * which have not updated + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{targetId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateTarget(@PathVariable("targetId") final String targetId, + @RequestBody final TargetRequestBody targetRest); + + /** + * Handles the DELETE request of deleting a target. + * + * @param targetId + * the ID of the target to be deleted + * @return If the given targetId could exists and could be deleted Http OK. + * In any failure the JsonResponseExceptionHandler is handling the + * response. + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity deleteTarget(@PathVariable("targetId") final String targetId); + + /** + * Handles the GET request of retrieving the attributes of a specific + * target. + * + * @param targetId + * the ID of the target to retrieve the attributes. + * @return the target attributes as map response with status OK + * @throws EntityNotFoundException + * in case no target with the given {@code targetId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/attributes", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getAttributes(@PathVariable("targetId") final String targetId); + + /** + * Handles the GET request of retrieving the Actions of a specific target. + * + * @param targetId + * to load actions for + * @param pagingOffsetParam + * the offset of list of targets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=status==pending} + * @return a list of all Actions for a defined or default page request with + * status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getActionHistory(@PathVariable("targetId") final String targetId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a specific Actions of a specific + * Target. + * + * @param targetId + * to load the action for + * @param actionId + * to load + * @return the action + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getAction(@PathVariable("targetId") final String targetId, + @PathVariable("actionId") final Long actionId); + + /** + * Handles the DELETE request of canceling an specific Actions of a specific + * Target. + * + * @param targetId + * the ID of the target in the URL path parameter + * @param actionId + * the ID of the action in the URL path parameter + * @param force + * optional parameter, which indicates a force cancel + * @return status no content in case cancellation was successful + * @throws CancelActionNotAllowedException + * if the given action is not active and cannot be canceled. + * @throws EntityNotFoundException + * if the target or the action is not found + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}/actions/{actionId}") + public ResponseEntity cancelAction(@PathVariable("targetId") final String targetId, + @PathVariable("actionId") final Long actionId, + @RequestParam(value = "force", required = false, defaultValue = "false") final boolean force); + + /** + * Handles the GET request of retrieving the ActionStatus of a specific + * target and action. + * + * @param targetId + * of the the action + * @param actionId + * of the status we are intend to load + * @param pagingOffsetParam + * the offset of list of targets for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @return a list of all ActionStatus for a defined or default page request + * with status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}/status", produces = { + "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getActionStatusList(@PathVariable("targetId") final String targetId, + @PathVariable("actionId") final Long actionId, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam); + + /** + * Handles the GET request of retrieving the assigned distribution set of an + * specific target. + * + * @param targetId + * the ID of the target to retrieve the assigned distribution + * @return the assigned distribution set with status OK, if none is assigned + * than {@code null} content (e.g. "{}") + * @throws EntityNotFoundException + * in case no target with the given {@code targetId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/assignedDS", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getAssignedDistributionSet( + @PathVariable("targetId") final String targetId); + + /** + * Changes the assigned distribution set of a target. + * + * @param targetId + * of the target to change + * @param dsId + * of the distributionset that is to be assigned + * @return http status + * + * @throws EntityNotFoundException + * in case no target with the given {@code targetId} exists. + * + */ + @RequestMapping(method = RequestMethod.POST, value = "/{targetId}/assignedDS", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity postAssignedDistributionSet(@PathVariable("targetId") final String targetId, + @RequestBody final DistributionSetAssigmentRest dsId); + + /** + * Handles the GET request of retrieving the installed distribution set of + * an specific target. + * + * @param targetId + * the ID of the target to retrieve + * @return the assigned installed set with status OK, if none is installed + * than {@code null} content (e.g. "{}") + * @throws EntityNotFoundException + * in case no target with the given {@code targetId} exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/installedDS", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getInstalledDistributionSet( + @PathVariable("targetId") final String targetId); + +} \ No newline at end of file diff --git a/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/TargetTagRestApi.java b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/TargetTagRestApi.java new file mode 100644 index 000000000..59770db08 --- /dev/null +++ b/hawkbit-rest-api/src/main/java/org/eclipse/hawkbit/rest/resource/api/TargetTagRestApi.java @@ -0,0 +1,196 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource.api; + +import java.util.List; + +import org.eclipse.hawkbit.rest.resource.RestConstants; +import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody; +import org.eclipse.hawkbit.rest.resource.model.tag.TagPagedList; +import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; +import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; +import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; +import org.eclipse.hawkbit.rest.resource.model.tag.TargetTagAssigmentResultRest; +import org.eclipse.hawkbit.rest.resource.model.target.TargetsRest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; + +/** + * REST Resource handling for TargetTag CRUD operations. + * + */ +@RequestMapping(RestConstants.TARGET_TAG_V1_REQUEST_MAPPING) +public interface TargetTagRestApi { + + /** + * Handles the GET request of retrieving all target tags. + * + * @param pagingOffsetParam + * the offset of list of target tags for pagination, might not be + * present in the rest request then default value will be applied + * @param pagingLimitParam + * the limit of the paged request, might not be present in the + * rest request then default value will be applied + * @param sortParam + * the sorting parameter in the request URL, syntax + * {@code field:direction, field:direction} + * @param rsqlParam + * the search parameter in the request URL, syntax + * {@code q=name==abc} + * @return a list of all target tags for a defined or default page request + * with status OK. The response is always paged. In any failure the + * JsonResponseExceptionHandler is handling the response. + */ + @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getTargetTags( + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, + @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam); + + /** + * Handles the GET request of retrieving a single target tag. + * + * @param targetTagId + * the ID of the target tag to retrieve + * + * @return a single target tag with status OK. + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.GET, value = "/{targetTagId}", produces = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity getTargetTag(@PathVariable("targetTagId") final Long targetTagId); + + /** + * Handles the POST request of creating new target tag. The request body + * must always be a list of tags. + * + * @param tags + * the target tags to be created. + * @return In case all modules could successful created the ResponseEntity + * with status code 201 - Created. The Response Body are the created + * target tags but without ResponseBody. + */ + @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity createTargetTags(@RequestBody final List tags); + + /** + * + * Handles the PUT request of updating a single targetr tag. + * + * @param targetTagId + * the ID of the target tag + * @param restTargetTagRest + * the the request body to be updated + * @return status OK if update is successful and the updated target tag. + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.PUT, value = "/{targetTagId}", consumes = { "application/hal+json", + MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + public ResponseEntity updateTagretTag(@PathVariable("targetTagId") final Long targetTagId, + @RequestBody final TagRequestBodyPut restTargetTagRest); + + /** + * Handles the DELETE request for a single target tag. + * + * @param targetTagId + * the ID of the target tag + * @return status OK if delete as successfully. + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + * + */ + @RequestMapping(method = RequestMethod.DELETE, value = "/{targetTagId}") + public ResponseEntity deleteTargetTag(@PathVariable("targetTagId") final Long targetTagId); + + /** + * Handles the GET request of retrieving all assigned targets by the given + * tag id. + * + * @param targetTagId + * the ID of the target tag to retrieve + * + * @return the list of assigned targets. + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.GET, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING) + public ResponseEntity getAssignedTargets(@PathVariable("targetTagId") final Long targetTagId); + + /** + * Handles the POST request to toggle the assignment of targets by the given + * tag id. + * + * @param targetTagId + * the ID of the target tag to retrieve + * @param assignedTargetRequestBodies + * list of target ids to be toggled + * + * @return the list of assigned targets and unassigned targets. + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.POST, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING + + "/toggleTagAssignment") + public ResponseEntity toggleTagAssignment( + @PathVariable("targetTagId") final Long targetTagId, + @RequestBody final List assignedTargetRequestBodies); + + /** + * Handles the POST request to assign targets to the given tag id. + * + * @param targetTagId + * the ID of the target tag to retrieve + * @param assignedTargetRequestBodies + * list of target ids to be assigned + * + * @return the list of assigned targets. + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.POST, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING) + public ResponseEntity assignTargets(@PathVariable("targetTagId") final Long targetTagId, + @RequestBody final List assignedTargetRequestBodies); + + /** + * Handles the DELETE request to unassign all targets from the given tag id. + * + * @param targetTagId + * the ID of the target tag to retrieve + * @return http status code + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.DELETE, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING) + public ResponseEntity unassignTargets(@PathVariable("targetTagId") final Long targetTagId); + + /** + * Handles the DELETE request to unassign one target from the given tag id. + * + * @param targetTagId + * the ID of the target tag + * @param controllerId + * the ID of the target to unassign + * @return http status code + * @throws EntityNotFoundException + * in case the given {@code targetTagId} doesn't exists. + */ + @RequestMapping(method = RequestMethod.DELETE, value = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING + + "/{controllerId}") + public ResponseEntity unassignTarget(@PathVariable("targetTagId") final Long targetTagId, + @PathVariable("controllerId") final String controllerId); +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetMapper.java index 830b47798..9ae133dd5 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetMapper.java @@ -22,6 +22,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi; import org.eclipse.hawkbit.rest.resource.model.MetadataRest; import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRequestBodyPost; import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetRest; @@ -169,13 +171,13 @@ public final class DistributionSetMapper { response.setRequiredMigrationStep(distributionSet.isRequiredMigrationStep()); response.add( - linkTo(methodOn(DistributionSetResource.class).getDistributionSet(response.getDsId())).withRel("self")); + linkTo(methodOn(DistributionSetRestApi.class).getDistributionSet(response.getDsId())).withRel("self")); response.add(linkTo( - methodOn(DistributionSetTypeResource.class).getDistributionSetType(distributionSet.getType().getId())) + methodOn(DistributionSetTypeRestApi.class).getDistributionSetType(distributionSet.getType().getId())) .withRel("type")); - response.add(linkTo(methodOn(DistributionSetResource.class).getMetadata(response.getDsId(), + response.add(linkTo(methodOn(DistributionSetRestApi.class).getMetadata(response.getDsId(), Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET), Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, null)) .withRel("metadata")); diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java index b0a245915..a4c71378d 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetResource.java @@ -30,6 +30,7 @@ import org.eclipse.hawkbit.repository.model.DsMetadataCompositeKey; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.rest.resource.model.MetadataRest; import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList; @@ -51,25 +52,14 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * REST Resource handling for {@link DistributionSet} CRUD operations. - * - * - * - * */ @RestController -@RequestMapping(RestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) -public class DistributionSetResource { +public class DistributionSetResource implements DistributionSetRestApi { private static final Logger LOG = LoggerFactory.getLogger(DistributionSetResource.class); @Autowired @@ -90,32 +80,9 @@ public class DistributionSetResource { @Autowired private DistributionSetManagement distributionSetManagement; - /** - * Handles the GET request of retrieving all {@link DistributionSet}s within - * SP. - * - * @param pagingOffsetParam - * the offset of list of sets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a list of all set for a defined or default page request with - * status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getDistributionSets( - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getDistributionSets(final int pagingOffsetParam, + final int pagingLimitParam, final String sortParam, final String rsqlParam) { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -124,99 +91,51 @@ public class DistributionSetResource { final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); final Page findDsPage; if (rsqlParam != null) { - findDsPage = distributionSetManagement.findDistributionSetsAll( + findDsPage = this.distributionSetManagement.findDistributionSetsAll( RSQLUtility.parse(rsqlParam, DistributionSetFields.class), pageable, false); } else { - findDsPage = distributionSetManagement.findDistributionSetsAll(pageable, false, null); + findDsPage = this.distributionSetManagement.findDistributionSetsAll(pageable, false, null); } final List rest = DistributionSetMapper.toResponseFromDsList(findDsPage.getContent()); return new ResponseEntity<>(new DistributionSetPagedList(rest, findDsPage.getTotalElements()), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single {@link DistributionSet} - * within SP. - * - * @param distributionSetId - * the ID of the set to retrieve - * - * @return a single {@link DistributionSet} with status OK. - * - * @throws EntityNotFoundException - * in case no {@link DistributionSet} with the given ID exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getDistributionSet(@PathVariable final Long distributionSetId) { + @Override + public ResponseEntity getDistributionSet(final Long distributionSetId) { final DistributionSet foundDs = findDistributionSetWithExceptionIfNotFound(distributionSetId); return new ResponseEntity<>(DistributionSetMapper.toResponse(foundDs), HttpStatus.OK); } - /** - * Handles the POST request of creating new distribution sets within SP. The - * request body must always be a list of sets. The requests is delegating to - * the {@link SoftwareManagement#createDistributionSet(DistributionSet))}. - * - * @param sets - * the {@link DistributionSet}s to be created. - * @return In case all sets could successful created the ResponseEntity with - * status code 201 - Created but without ResponseBody. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE, - "application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity createDistributionSets( - @RequestBody final List sets) { + final List sets) { LOG.debug("creating {} distribution sets", sets.size()); // set default Ds type if ds type is null - sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType( - systemManagement.getTenantMetadata(currentTenant.getCurrentTenant()).getDefaultDsType().getKey())); + sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(this.systemManagement + .getTenantMetadata(this.currentTenant.getCurrentTenant()).getDefaultDsType().getKey())); - final Iterable createdDSets = distributionSetManagement.createDistributionSets( - DistributionSetMapper.dsFromRequest(sets, softwareManagement, distributionSetManagement)); + final Iterable createdDSets = this.distributionSetManagement.createDistributionSets( + DistributionSetMapper.dsFromRequest(sets, this.softwareManagement, this.distributionSetManagement)); LOG.debug("{} distribution sets created, return status {}", sets.size(), HttpStatus.CREATED); return new ResponseEntity<>(DistributionSetMapper.toResponseDistributionSets(createdDSets), HttpStatus.CREATED); } - /** - * Handles the DELETE request for a single {@link DistributionSet} within - * SP. - * - * @param distributionSetId - * the ID of the {@link DistributionSet} to delete - * @return status OK if delete as successful. - * - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}") - public ResponseEntity deleteDistributionSet(@PathVariable final Long distributionSetId) { + @Override + public ResponseEntity deleteDistributionSet(final Long distributionSetId) { final DistributionSet set = findDistributionSetWithExceptionIfNotFound(distributionSetId); - distributionSetManagement.deleteDistributionSet(set); + this.distributionSetManagement.deleteDistributionSet(set); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the UPDATE request for a single {@link DistributionSet} within - * SP. - * - * @param distributionSetId - * the ID of the {@link DistributionSet} to delete - * @param toUpdate - * with the data that needs updating - * - * @return status OK if update as successful with updated content. - * - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity updateDistributionSet(@PathVariable final Long distributionSetId, - @RequestBody final DistributionSetRequestBodyPut toUpdate) { + @Override + public ResponseEntity updateDistributionSet(final Long distributionSetId, + final DistributionSetRequestBodyPut toUpdate) { final DistributionSet set = findDistributionSetWithExceptionIfNotFound(distributionSetId); if (toUpdate.getDescription() != null) { @@ -231,38 +150,13 @@ public class DistributionSetResource { set.setVersion(toUpdate.getVersion()); } return new ResponseEntity<>( - DistributionSetMapper.toResponse(distributionSetManagement.updateDistributionSet(set)), HttpStatus.OK); + DistributionSetMapper.toResponse(this.distributionSetManagement.updateDistributionSet(set)), + HttpStatus.OK); } - /** - * Handles the GET request of retrieving assigned targets to a specific - * distribution set. - * - * @param distributionSetId - * the ID of the distribution set to retrieve the assigned - * targets - * @param pagingOffsetParam - * the offset of list of targets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return status OK if get request is successful with the paged list of - * targets - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedTargets", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getAssignedTargets(@PathVariable final Long distributionSetId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getAssignedTargets(final Long distributionSetId, final int pagingOffsetParam, + final int pagingLimitParam, final String sortParam, final String rsqlParam) { // check if distribution set exists otherwise throw exception // immediately @@ -275,45 +169,19 @@ public class DistributionSetResource { final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); final Page targetsAssignedDS; if (rsqlParam != null) { - targetsAssignedDS = targetManagement.findTargetByAssignedDistributionSet(distributionSetId, + targetsAssignedDS = this.targetManagement.findTargetByAssignedDistributionSet(distributionSetId, RSQLUtility.parse(rsqlParam, TargetFields.class), pageable); } else { - targetsAssignedDS = targetManagement.findTargetByAssignedDistributionSet(distributionSetId, pageable); + targetsAssignedDS = this.targetManagement.findTargetByAssignedDistributionSet(distributionSetId, pageable); } return new ResponseEntity<>(new TargetPagedList(TargetMapper.toResponse(targetsAssignedDS.getContent()), targetsAssignedDS.getTotalElements()), HttpStatus.OK); } - /** - * Handles the GET request of retrieving installed targets to a specific - * distribution set. - * - * @param distributionSetId - * the ID of the distribution set to retrieve the assigned - * targets - * @param pagingOffsetParam - * the offset of list of targets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return status OK if get request is successful with the paged list of - * targets - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/installedTargets", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getInstalledTargets(@PathVariable final Long distributionSetId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getInstalledTargets(final Long distributionSetId, + final int pagingOffsetParam, final int pagingLimitParam, final String sortParam, final String rsqlParam) { // check if distribution set exists otherwise throw exception // immediately findDistributionSetWithExceptionIfNotFound(distributionSetId); @@ -325,36 +193,22 @@ public class DistributionSetResource { final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); final Page targetsInstalledDS; if (rsqlParam != null) { - targetsInstalledDS = targetManagement.findTargetByInstalledDistributionSet(distributionSetId, + targetsInstalledDS = this.targetManagement.findTargetByInstalledDistributionSet(distributionSetId, RSQLUtility.parse(rsqlParam, TargetFields.class), pageable); } else { - targetsInstalledDS = targetManagement.findTargetByInstalledDistributionSet(distributionSetId, pageable); + targetsInstalledDS = this.targetManagement.findTargetByInstalledDistributionSet(distributionSetId, + pageable); } return new ResponseEntity<>(new TargetPagedList(TargetMapper.toResponse(targetsInstalledDS.getContent()), targetsInstalledDS.getTotalElements()), HttpStatus.OK); } - /** - * Handles the POST request of assigning multiple targets to a single - * distribution set. - * - * @param distributionSetId - * the ID of the distribution set within the URL path parameter - * @param targetIds - * the IDs of the target which should get assigned to the - * distribution set given in the response body - * @return status OK if the assignment of the targets was successful and a - * complex return body which contains information about the assigned - * targets and the already assigned targets counters - */ - @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedTargets", consumes = { - "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity createAssignedTarget(@PathVariable final Long distributionSetId, - @RequestBody final List targetIds) { + @Override + public ResponseEntity createAssignedTarget(final Long distributionSetId, + final List targetIds) { - final DistributionSetAssignmentResult assignDistributionSet = deployManagament.assignDistributionSet( + final DistributionSetAssignmentResult assignDistributionSet = this.deployManagament.assignDistributionSet( distributionSetId, targetIds.stream() .map(t -> new TargetWithActionType(t.getId(), @@ -364,33 +218,9 @@ public class DistributionSetResource { return new ResponseEntity<>(DistributionSetMapper.toResponse(assignDistributionSet), HttpStatus.OK); } - /** - * Gets a paged list of meta data for a distribution set. - * - * @param distributionSetId - * the ID of the distribution set for the meta data - * @param pagingOffsetParam - * the offset of list of targets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=key==abc} - * @return status OK if get request is successful with the paged list of - * meta data - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getMetadata(@PathVariable final Long distributionSetId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getMetadata(final Long distributionSetId, final int pagingOffsetParam, + final int pagingLimitParam, final String sortParam, final String rsqlParam) { // check if distribution set exists otherwise throw exception // immediately @@ -404,11 +234,11 @@ public class DistributionSetResource { final Page metaDataPage; if (rsqlParam != null) { - metaDataPage = distributionSetManagement.findDistributionSetMetadataByDistributionSetId(distributionSetId, - RSQLUtility.parse(rsqlParam, DistributionSetMetadataFields.class), pageable); + metaDataPage = this.distributionSetManagement.findDistributionSetMetadataByDistributionSetId( + distributionSetId, RSQLUtility.parse(rsqlParam, DistributionSetMetadataFields.class), pageable); } else { - metaDataPage = distributionSetManagement.findDistributionSetMetadataByDistributionSetId(distributionSetId, - pageable); + metaDataPage = this.distributionSetManagement + .findDistributionSetMetadataByDistributionSetId(distributionSetId, pageable); } return new ResponseEntity<>( @@ -418,119 +248,59 @@ public class DistributionSetResource { } - /** - * Gets a single meta data value for a specific key of a distribution set. - * - * @param distributionSetId - * the ID of the distribution set to get the meta data from - * @param metadataKey - * the key of the meta data entry to retrieve the value from - * @return status OK if get request is successful with the value of the meta - * data - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/metadata/{metadataKey}", produces = { - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getMetadataValue(@PathVariable final Long distributionSetId, - @PathVariable final String metadataKey) { + @Override + public ResponseEntity getMetadataValue(final Long distributionSetId, final String metadataKey) { // check if distribution set exists otherwise throw exception // immediately final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId); - final DistributionSetMetadata findOne = distributionSetManagement + final DistributionSetMetadata findOne = this.distributionSetManagement .findOne(new DsMetadataCompositeKey(ds, metadataKey)); return ResponseEntity. ok(DistributionSetMapper.toResponseDsMetadata(findOne)); } - /** - * Updates a single meta data value of a distribution set. - * - * @param distributionSetId - * the ID of the distribution set to update the meta data entry - * @param metadataKey - * the key of the meta data to update the value - * @return status OK if the update request is successful and the updated - * meta data result - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetId}/metadata/{metadataKey}", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity updateMetadata(@PathVariable final Long distributionSetId, - @PathVariable final String metadataKey, @RequestBody final MetadataRest metadata) { + @Override + public ResponseEntity updateMetadata(final Long distributionSetId, final String metadataKey, + final MetadataRest metadata) { // check if distribution set exists otherwise throw exception // immediately final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId); - final DistributionSetMetadata updated = distributionSetManagement + final DistributionSetMetadata updated = this.distributionSetManagement .updateDistributionSetMetadata(new DistributionSetMetadata(metadataKey, ds, metadata.getValue())); return ResponseEntity.ok(DistributionSetMapper.toResponseDsMetadata(updated)); } - /** - * Deletes a single meta data entry from the distribution set. - * - * @param distributionSetId - * the ID of the distribution set to delete the meta data entry - * @param metadataKey - * the key of the meta data to delete - * @return status OK if the delete request is successful - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/metadata/{metadataKey}") - public ResponseEntity deleteMetadata(@PathVariable final Long distributionSetId, - @PathVariable final String metadataKey) { + @Override + public ResponseEntity deleteMetadata(final Long distributionSetId, final String metadataKey) { // check if distribution set exists otherwise throw exception // immediately final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId); - distributionSetManagement.deleteDistributionSetMetadata(new DsMetadataCompositeKey(ds, metadataKey)); + this.distributionSetManagement.deleteDistributionSetMetadata(new DsMetadataCompositeKey(ds, metadataKey)); return ResponseEntity.ok().build(); } - /** - * Creates a list of meta data for a specific distribution set. - * - * @param distributionSetId - * the ID of the distribution set to create meta data for - * @param metadataRest - * the list of meta data entries to create - * @return status created if post request is successful with the value of - * the created meta data - */ - @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/metadata", consumes = { - MediaType.APPLICATION_JSON_VALUE, - "application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity> createMetadata(@PathVariable final Long distributionSetId, - @RequestBody final List metadataRest) { + @Override + public ResponseEntity> createMetadata(final Long distributionSetId, + final List metadataRest) { // check if distribution set exists otherwise throw exception // immediately final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId); - final List created = distributionSetManagement + final List created = this.distributionSetManagement .createDistributionSetMetadata(DistributionSetMapper.fromRequestDsMetadata(ds, metadataRest)); return new ResponseEntity<>(DistributionSetMapper.toResponseDsMetadata(created), HttpStatus.CREATED); } - /** - * Assigns a list of software modules to a distribution set. - * - * @param distributionSetId - * the ID of the distribution set to assign software modules for - * @param softwareModuleIDs - * the list of software modules ids to assign - * @return {@link HttpStatus#OK} - * - * @throws EntityNotFoundException - * in case no distribution set with the given - * {@code distributionSetId} exists. - */ - @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetId}/assignedSM", consumes = { - MediaType.APPLICATION_JSON_VALUE, - "application/hal+json" }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity assignSoftwareModules(@PathVariable final Long distributionSetId, - @RequestBody final List softwareModuleIDs) { + @Override + public ResponseEntity assignSoftwareModules(final Long distributionSetId, + final List softwareModuleIDs) { // check if distribution set exists otherwise throw exception // immediately final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId); final Set softwareModuleToBeAssigned = new HashSet<>(); for (final SoftwareModuleAssigmentRest sm : softwareModuleIDs) { - final SoftwareModule softwareModule = softwareManagement.findSoftwareModuleById(sm.getId()); + final SoftwareModule softwareModule = this.softwareManagement.findSoftwareModuleById(sm.getId()); if (softwareModule != null) { softwareModuleToBeAssigned.add(softwareModule); } else { @@ -538,63 +308,23 @@ public class DistributionSetResource { } } // Add Softwaremodules to DisSet only if all of them were found - distributionSetManagement.assignSoftwareModules(ds, softwareModuleToBeAssigned); + this.distributionSetManagement.assignSoftwareModules(ds, softwareModuleToBeAssigned); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Deletes the assignment of the software module form the distribution set. - * - * @param distributionSetId - * the ID of the distribution set to reject the software module - * for - * @param softwareModuleId - * the software module id to get rejected form the distribution - * set - * @return status OK if rejection was successful. - * @throws EntityNotFoundException - * in case no distribution set with the given - * {@code distributionSetId} exists. - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetId}/assignedSM/{softwareModuleId}") - public ResponseEntity deleteAssignSoftwareModules(@PathVariable final Long distributionSetId, - @PathVariable final Long softwareModuleId) { + @Override + public ResponseEntity deleteAssignSoftwareModules(final Long distributionSetId, final Long softwareModuleId) { // check if distribution set and software module exist otherwise throw // exception immediately final DistributionSet ds = findDistributionSetWithExceptionIfNotFound(distributionSetId); final SoftwareModule sm = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId); - distributionSetManagement.unassignSoftwareModule(ds, sm); + this.distributionSetManagement.unassignSoftwareModule(ds, sm); return ResponseEntity.ok().build(); } - /** - * Handles the GET request for retrieving the assigned software modules of a - * specific distribution set. - * - * @param distributionSetId - * the ID of the distribution to retrieve - * @param pagingOffsetParam - * the offset of list of sets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @return a list of the assigned software modules of a distribution set - * with status OK, if none is assigned than {@code null} - * @throws EntityNotFoundException - * in case no distribution set with the given - * {@code distributionSetId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetId}/assignedSM", produces = { - "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getAssignedSoftwareModules( - @PathVariable final Long distributionSetId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam) { + @Override + public ResponseEntity getAssignedSoftwareModules(final Long distributionSetId, + final int pagingOffsetParam, final int pagingLimitParam, final String sortParam) { // check if distribution set exists otherwise throw exception // immediately final DistributionSet foundDs = findDistributionSetWithExceptionIfNotFound(distributionSetId); @@ -602,7 +332,7 @@ public class DistributionSetResource { final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); final Sort sorting = PagingUtility.sanitizeSoftwareModuleSortParam(sortParam); final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); - final Page softwaremodules = softwareManagement.findSoftwareModuleByAssignedTo(pageable, + final Page softwaremodules = this.softwareManagement.findSoftwareModuleByAssignedTo(pageable, foundDs); return new ResponseEntity<>( new SoftwareModulePagedList(SoftwareModuleMapper.toResponse(softwaremodules.getContent()), @@ -611,7 +341,7 @@ public class DistributionSetResource { } private DistributionSet findDistributionSetWithExceptionIfNotFound(final Long distributionSetId) { - final DistributionSet set = distributionSetManagement.findDistributionSetById(distributionSetId); + final DistributionSet set = this.distributionSetManagement.findDistributionSetById(distributionSetId); if (set == null) { throw new EntityNotFoundException("DistributionSet with Id {" + distributionSetId + "} does not exist"); } @@ -620,7 +350,7 @@ public class DistributionSetResource { } private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId) { - final SoftwareModule sm = softwareManagement.findSoftwareModuleById(softwareModuleId); + final SoftwareModule sm = this.softwareManagement.findSoftwareModuleById(softwareModuleId); if (sm == null) { throw new EntityNotFoundException("SoftwareModule with Id {" + softwareModuleId + "} does not exist"); } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java index 99e22436e..c395863ab 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTagResource.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssigmentResult; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTagRestApi; import org.eclipse.hawkbit.rest.resource.model.distributionset.DistributionSetsRest; import org.eclipse.hawkbit.rest.resource.model.tag.AssignedDistributionSetRequestBody; import org.eclipse.hawkbit.rest.resource.model.tag.DistributionSetTagAssigmentResultRest; @@ -34,13 +35,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -48,8 +43,7 @@ import org.springframework.web.bind.annotation.RestController; * */ @RestController -@RequestMapping(RestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) -public class DistributionSetTagResource { +public class DistributionSetTagResource implements DistributionSetTagRestApi { private static final Logger LOG = LoggerFactory.getLogger(DistributionSetTagResource.class); @Autowired @@ -58,32 +52,9 @@ public class DistributionSetTagResource { @Autowired private DistributionSetManagement distributionSetManagement; - /** - * Handles the GET request of retrieving all DistributionSet tags. - * - * @param pagingOffsetParam - * the offset of list of DistributionSet tags for pagination, - * might not be present in the rest request then default value - * will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a list of all target tags for a defined or default page request - * with status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getDistributionSetTags( - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getDistributionSetTags(final int pagingOffsetParam, final int pagingLimitParam, + final String sortParam, final String rsqlParam) { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -93,11 +64,11 @@ public class DistributionSetTagResource { final Slice findTargetsAll; final Long countTargetsAll; if (rsqlParam == null) { - findTargetsAll = tagManagement.findAllDistributionSetTags(pageable); - countTargetsAll = tagManagement.countTargetTags(); + findTargetsAll = this.tagManagement.findAllDistributionSetTags(pageable); + countTargetsAll = this.tagManagement.countTargetTags(); } else { - final Page findTargetPage = tagManagement + final Page findTargetPage = this.tagManagement .findAllDistributionSetTags(RSQLUtility.parse(rsqlParam, TagFields.class), pageable); countTargetsAll = findTargetPage.getTotalElements(); findTargetsAll = findTargetPage; @@ -108,141 +79,63 @@ public class DistributionSetTagResource { return new ResponseEntity<>(new TagPagedList(rest, countTargetsAll), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single distribution set tag. - * - * @param distributionsetTagId - * the ID of the distribution set tag to retrieve - * - * @return a single distribution set tag with status OK. - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionsetTagId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getDistributionSetTag(@PathVariable final Long distributionsetTagId) { + @Override + public ResponseEntity getDistributionSetTag(final Long distributionsetTagId) { final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); return new ResponseEntity<>(TagMapper.toResponse(tag), HttpStatus.OK); } - /** - * Handles the POST request of creating new distribution set tag. The - * request body must always be a list of tags. - * - * @param tags - * the distribution set tags to be created. - * @return In case all modules could successful created the ResponseEntity - * with status code 201 - Created. The Response Body are the created - * distribution set tags but without ResponseBody. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity createDistributionSetTags(@RequestBody final List tags) { + @Override + public ResponseEntity createDistributionSetTags(final List tags) { LOG.debug("creating {} ds tags", tags.size()); - final List createdTags = tagManagement + final List createdTags = this.tagManagement .createDistributionSetTags(TagMapper.mapDistributionSetTagFromRequest(tags)); return new ResponseEntity<>(TagMapper.toResponseDistributionSetTag(createdTags), HttpStatus.CREATED); } - /** - * - * Handles the PUT request of updating a single distribution set tag. - * - * @param distributionsetTagId - * the ID of the distribution set tag - * @param restDSTagRest - * the the request body to be updated - * @return status OK if update is successful and the updated distribution - * set tag. - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{distributionsetTagId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity updateDistributionSetTag(@PathVariable final Long distributionsetTagId, - @RequestBody final TagRequestBodyPut restDSTagRest) { + @Override + public ResponseEntity updateDistributionSetTag(final Long distributionsetTagId, + final TagRequestBodyPut restDSTagRest) { LOG.debug("update {} ds tag", restDSTagRest); final DistributionSetTag distributionSetTag = findDistributionTagById(distributionsetTagId); TagMapper.updateTag(restDSTagRest, distributionSetTag); - final DistributionSetTag updateDistributionSetTag = tagManagement.updateDistributionSetTag(distributionSetTag); + final DistributionSetTag updateDistributionSetTag = this.tagManagement + .updateDistributionSetTag(distributionSetTag); LOG.debug("ds tag updated"); return new ResponseEntity<>(TagMapper.toResponse(updateDistributionSetTag), HttpStatus.OK); } - /** - * Handles the DELETE request for a single distribution set tag. - * - * @param distributionsetTagId - * the ID of the distribution set tag - * @return status OK if delete as successfully. - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - * - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionsetTagId}") - public ResponseEntity deleteDistributionSetTag(@PathVariable final Long distributionsetTagId) { + @Override + public ResponseEntity deleteDistributionSetTag(final Long distributionsetTagId) { LOG.debug("Delete {} distribution set tag", distributionsetTagId); final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); - tagManagement.deleteDistributionSetTag(tag.getName()); + this.tagManagement.deleteDistributionSetTag(tag.getName()); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the GET request of retrieving all assigned distribution sets by - * the given tag id. - * - * @param distributionsetTagId - * the ID of the distribution set tag - * - * @return the list of assigned distribution sets. - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.GET, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) - public ResponseEntity getAssignedDistributionSets( - @PathVariable final Long distributionsetTagId) { + @Override + public ResponseEntity getAssignedDistributionSets(final Long distributionsetTagId) { final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); return new ResponseEntity<>( DistributionSetMapper.toResponseDistributionSets(tag.getAssignedToDistributionSet()), HttpStatus.OK); } - /** - * Handles the POST request to toggle the assignment of distribution sets by - * the given tag id. - * - * @param distributionsetTagIds - * the ID of the distribution set tag to retrieve - * @param assignedDSRequestBodies - * list of distribution set ids to be toggled - * - * @return the list of assigned distribution sets and unassigned - * distribution sets. - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING - + "/toggleTagAssignment") - public ResponseEntity toggleTagAssignment( - @PathVariable final Long distributionsetTagId, - @RequestBody final List assignedDSRequestBodies) { + @Override + public ResponseEntity toggleTagAssignment(final Long distributionsetTagId, + final List assignedDSRequestBodies) { LOG.debug("Toggle distribution set assignment {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId); final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); - final DistributionSetTagAssigmentResult assigmentResult = distributionSetManagement + final DistributionSetTagAssigmentResult assigmentResult = this.distributionSetManagement .toggleTagAssignment(findDistributionSetIds(assignedDSRequestBodies), tag.getName()); final DistributionSetTagAssigmentResultRest tagAssigmentResultRest = new DistributionSetTagAssigmentResultRest(); @@ -257,44 +150,20 @@ public class DistributionSetTagResource { return new ResponseEntity<>(tagAssigmentResultRest, HttpStatus.OK); } - /** - * Handles the POST request to assign distribution sets to the given tag id. - * - * @param distributionsetTagId - * the ID of the distribution set tag to retrieve - * @param assignedDSRequestBodies - * list of distribution sets ids to be assigned - * - * @return the list of assigned distribution set. - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.POST, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) - public ResponseEntity assignDistributionSets(@PathVariable final Long distributionsetTagId, - @RequestBody final List assignedDSRequestBodies) { + @Override + public ResponseEntity assignDistributionSets(final Long distributionsetTagId, + final List assignedDSRequestBodies) { LOG.debug("Assign DistributionSet {} for ds tag {}", assignedDSRequestBodies.size(), distributionsetTagId); final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); - final List assignedDs = distributionSetManagement + final List assignedDs = this.distributionSetManagement .assignTag(findDistributionSetIds(assignedDSRequestBodies), tag); LOG.debug("Assignd DistributionSet {}", assignedDs.size()); return new ResponseEntity<>(DistributionSetMapper.toResponseDistributionSets(assignedDs), HttpStatus.OK); } - /** - * Handles the DELETE request to unassign all distribution set from the - * given tag id. - * - * @param distributionsetTagId - * the ID of the distribution set tag to retrieve - * @return http status code - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING) - public ResponseEntity unassignDistributionSets(@PathVariable final Long distributionsetTagId) { + @Override + public ResponseEntity unassignDistributionSets(final Long distributionsetTagId) { LOG.debug("Unassign all DS for ds tag {}", distributionsetTagId); final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); if (tag.getAssignedToDistributionSet() == null) { @@ -302,36 +171,22 @@ public class DistributionSetTagResource { return new ResponseEntity<>(HttpStatus.OK); } - final List distributionSets = distributionSetManagement.unAssignAllDistributionSetsByTag(tag); + final List distributionSets = this.distributionSetManagement + .unAssignAllDistributionSetsByTag(tag); LOG.debug("Unassigned ds {}", distributionSets.size()); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the DELETE request to unassign one distribution set from the - * given tag id. - * - * @param distributionsetTagId - * the ID of the distribution set tag - * @param distributionsetId - * the ID of the distribution set to unassign - * @return http status code - * @throws EntityNotFoundException - * in case the given {@code distributionsetTagId} doesn't - * exists. - */ - @RequestMapping(method = RequestMethod.DELETE, value = RestConstants.DISTRIBUTIONSET_REQUEST_MAPPING - + "/{distributionsetId}") - public ResponseEntity unassignDistributionSet(@PathVariable final Long distributionsetTagId, - @PathVariable final Long distributionsetId) { + @Override + public ResponseEntity unassignDistributionSet(final Long distributionsetTagId, final Long distributionsetId) { LOG.debug("Unassign ds {} for ds tag {}", distributionsetId, distributionsetTagId); final DistributionSetTag tag = findDistributionTagById(distributionsetTagId); - distributionSetManagement.unAssignTag(distributionsetId, tag); + this.distributionSetManagement.unAssignTag(distributionsetId, tag); return new ResponseEntity<>(HttpStatus.OK); } private DistributionSetTag findDistributionTagById(final Long distributionsetTagId) { - final DistributionSetTag tag = tagManagement.findDistributionSetTagById(distributionsetTagId); + final DistributionSetTag tag = this.tagManagement.findDistributionSetTagById(distributionsetTagId); if (tag == null) { throw new EntityNotFoundException("Distribution Tag with Id {" + distributionsetTagId + "} does not exist"); } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeMapper.java index 0550e0fc5..92923cb56 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeMapper.java @@ -18,6 +18,7 @@ import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi; import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost; import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRest; import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypesRest; @@ -101,13 +102,13 @@ final class DistributionSetTypeMapper { result.setKey(type.getKey()); result.setModuleId(type.getId()); - result.add(linkTo(methodOn(DistributionSetTypeResource.class).getDistributionSetType(result.getModuleId())) + result.add(linkTo(methodOn(DistributionSetTypeRestApi.class).getDistributionSetType(result.getModuleId())) .withRel("self")); - result.add(linkTo(methodOn(DistributionSetTypeResource.class).getMandatoryModules(result.getModuleId())) + result.add(linkTo(methodOn(DistributionSetTypeRestApi.class).getMandatoryModules(result.getModuleId())) .withRel(RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULES)); - result.add(linkTo(methodOn(DistributionSetTypeResource.class).getOptionalModules(result.getModuleId())) + result.add(linkTo(methodOn(DistributionSetTypeRestApi.class).getOptionalModules(result.getModuleId())) .withRel(RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULES)); return result; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java index 19cf94f04..700ef3d96 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java @@ -19,6 +19,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTypeRestApi; import org.eclipse.hawkbit.rest.resource.model.IdRest; import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypePagedList; import org.eclipse.hawkbit.rest.resource.model.distributionsettype.DistributionSetTypeRequestBodyPost; @@ -33,12 +34,9 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @@ -47,12 +45,9 @@ import org.springframework.web.bind.annotation.RestController; * {@link Artifact} CRUD operations. * * - * - * */ @RestController -@RequestMapping(RestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) -public class DistributionSetTypeResource { +public class DistributionSetTypeResource implements DistributionSetTypeRestApi { @Autowired private SoftwareManagement softwareManagement; @@ -60,30 +55,7 @@ public class DistributionSetTypeResource { @Autowired private DistributionSetManagement distributionSetManagement; - /** - * Handles the GET request of retrieving all {@link DistributionSetType}s - * within SP. - * - * @param pagingOffsetParam - * the offset of list of modules for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * - * @return a list of all {@link DistributionSetType} for a defined or - * default page request with status OK. The response is always - * paged. In any failure the JsonResponseExceptionHandler is - * handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - + @Override public ResponseEntity getDistributionSetTypes( @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @@ -112,19 +84,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(new DistributionSetTypePagedList(rest, countModulesAll), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single - * {@link DistributionSetType} within SP. - * - * @param distributionSetTypeId - * the ID of the module type to retrieve - * - * @return a single softwareModule with status OK. - * @throws EntityNotFoundException - * in case no with the given {@code softwareModuleId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getDistributionSetType( @PathVariable final Long distributionSetTypeId) { final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); @@ -132,15 +92,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(DistributionSetTypeMapper.toResponse(foundType), HttpStatus.OK); } - /** - * Handles the DELETE request for a single Distribution Set Type within SP. - * - * @param distributionSetTypeId - * the ID of the module to retrieve - * @return status OK if delete as sucessfull. - * - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}") + @Override public ResponseEntity deleteDistributionSetType(@PathVariable final Long distributionSetTypeId) { final DistributionSetType module = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); @@ -149,17 +101,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the PUT request of updating a Distribution Set Type within SP. - * - * @param distributionSetTypeId - * the ID of the software module in the URL - * @param restDistributionSetType - * the module type to be updated. - * @return status OK if update is successful - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{distributionSetTypeId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity updateDistributionSetType( @PathVariable final Long distributionSetTypeId, @RequestBody final DistributionSetTypeRequestBodyPut restDistributionSetType) { @@ -176,19 +118,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(DistributionSetTypeMapper.toResponse(updatedDistributionSetType), HttpStatus.OK); } - /** - * Handles the POST request of creating new {@link DistributionSetType}s - * within SP. The request body must always be a list of types. - * - * @param distributionSetTypes - * the modules to be created. - * @return In case all modules could successful created the ResponseEntity - * with status code 201 - Created but without ResponseBody. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity createDistributionSetTypes( @RequestBody final List distributionSetTypes) { @@ -208,17 +138,7 @@ public class DistributionSetTypeResource { return module; } - /** - * Handles the GET request of retrieving the list of mandatory software - * module types in that distribution set type. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @return Unpaged list of module types and OK in case of success. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getMandatoryModules(@PathVariable final Long distributionSetTypeId) { final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); @@ -229,19 +149,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(rest, HttpStatus.OK); } - /** - * Handles the GET request of retrieving the single mandatory software - * module type in that distribution set type. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @param softwareModuleTypeId - * of {@link SoftwareModuleType}. - * @return Unpaged list of module types and OK in case of success. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES - + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getMandatoryModule(@PathVariable final Long distributionSetTypeId, @PathVariable final Long softwareModuleTypeId) { @@ -257,19 +165,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(foundSmType), HttpStatus.OK); } - /** - * Handles the GET request of retrieving the single optional software module - * type in that distribution set type. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @param softwareModuleTypeId - * of {@link SoftwareModuleType}. - * @return Unpaged list of module types and OK in case of success. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES - + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getOptionalModule(@PathVariable final Long distributionSetTypeId, @PathVariable final Long softwareModuleTypeId) { @@ -285,17 +181,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(foundSmType), HttpStatus.OK); } - /** - * Handles the GET request of retrieving the list of optional software - * module types in that distribution set type. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @return Unpaged list of module types and OK in case of success. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getOptionalModules(@PathVariable final Long distributionSetTypeId) { final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); @@ -306,20 +192,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(rest, HttpStatus.OK); } - /** - * Handles DELETE request for removing a mandatory module from the - * {@link DistributionSetType}. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @param softwareModuleTypeId - * of the {@link SoftwareModuleType} to remove - * - * @return OK if the request was successful - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES - + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity removeMandatoryModule(@PathVariable final Long distributionSetTypeId, @PathVariable final Long softwareModuleTypeId) { @@ -339,20 +212,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles DELETE request for removing an optional module from the - * {@link DistributionSetType}. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @param softwareModuleTypeId - * of the {@link SoftwareModuleType} to remove - * - * @return OK if the request was successful - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES - + "/{softwareModuleTypeId}", produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity removeOptionalModule(@PathVariable final Long distributionSetTypeId, @PathVariable final Long softwareModuleTypeId) { final DistributionSetType foundType = findDistributionSetTypeWithExceptionIfNotFound(distributionSetTypeId); @@ -371,21 +231,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the POST request for adding a mandatory software module type to a - * distribution set type. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @param smtId - * of the {@link SoftwareModuleType} to add - * - * @return OK if the request was successful - */ - @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity addMandatoryModule(@PathVariable final Long distributionSetTypeId, @RequestBody final IdRest smtId) { @@ -400,21 +246,7 @@ public class DistributionSetTypeResource { return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the POST request for adding an optional software module type to a - * distribution set type. - * - * @param distributionSetTypeId - * of the {@link DistributionSetType}. - * @param smtId - * of the {@link SoftwareModuleType} to add - * - * @return OK if the request was successful - */ - @RequestMapping(method = RequestMethod.POST, value = "/{distributionSetTypeId}/" - + RestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity addOptionalModule(@PathVariable final Long distributionSetTypeId, @RequestBody final IdRest smtId) { diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DownloadArtifactResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DownloadArtifactResource.java new file mode 100644 index 000000000..00f8f4756 --- /dev/null +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DownloadArtifactResource.java @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.rest.resource; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * @author Jonathan Knoblauch + * + */ +@RestController +@RequestMapping(RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) +public class DownloadArtifactResource { + + @Autowired + private SoftwareManagement softwareManagement; + + @Autowired + private ArtifactManagement artifactManagement; + + /** + * Handles the GET request for downloading an artifact. + * + * @param softwareModuleId + * of the parent SoftwareModule + * @param artifactId + * of the related LocalArtifact + * @param servletResponse + * of the servlet + * @param request + * of the client + * + * @return responseEntity with status ok if successful + */ + @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}/download") + @ResponseBody + public ResponseEntity downloadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, + @PathVariable("artifactId") final Long artifactId, final HttpServletResponse servletResponse, + final HttpServletRequest request) { + final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); + + if (null == module || !module.getLocalArtifact(artifactId).isPresent()) { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } + + final LocalArtifact artifact = module.getLocalArtifact(artifactId).get(); + final DbArtifact file = artifactManagement.loadLocalArtifactBinary(artifact); + + final String ifMatch = request.getHeader("If-Match"); + if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) { + return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED); + } + + return RestResourceConversionHelper.writeFileResponse(artifact, servletResponse, request, file); + + } + + private SoftwareModule findSoftwareModuleWithExceptionIfNotFound(final Long softwareModuleId, + final Long artifactId) { + final SoftwareModule module = softwareManagement.findSoftwareModuleById(softwareModuleId); + if (module == null) { + throw new EntityNotFoundException("SoftwareModule with Id {" + softwareModuleId + "} does not exist"); + } else if (artifactId != null && !module.getLocalArtifact(artifactId).isPresent()) { + throw new EntityNotFoundException("Artifact with Id {" + artifactId + "} does not exist"); + } + return module; + } + +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutMapper.java index 712595638..c6be219ba 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutMapper.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondit import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessAction; import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.hawkbit.rest.resource.api.RolloutRestApi; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutCondition.Condition; import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutErrorAction.ErrorAction; @@ -70,12 +71,12 @@ final class RolloutMapper { rollout.getTotalTargetCountStatus().getTotalTargetCountByStatus(status)); } - body.add(linkTo(methodOn(RolloutResource.class).getRollout(rollout.getId())).withRel("self")); - body.add(linkTo(methodOn(RolloutResource.class).start(rollout.getId(), false)).withRel("start")); - body.add(linkTo(methodOn(RolloutResource.class).start(rollout.getId(), true)).withRel("startAsync")); - body.add(linkTo(methodOn(RolloutResource.class).pause(rollout.getId())).withRel("pause")); - body.add(linkTo(methodOn(RolloutResource.class).resume(rollout.getId())).withRel("resume")); - body.add(linkTo(methodOn(RolloutResource.class).getRolloutGroups(rollout.getId(), + body.add(linkTo(methodOn(RolloutRestApi.class).getRollout(rollout.getId())).withRel("self")); + body.add(linkTo(methodOn(RolloutRestApi.class).start(rollout.getId(), false)).withRel("start")); + body.add(linkTo(methodOn(RolloutRestApi.class).start(rollout.getId(), true)).withRel("startAsync")); + body.add(linkTo(methodOn(RolloutRestApi.class).pause(rollout.getId())).withRel("pause")); + body.add(linkTo(methodOn(RolloutRestApi.class).resume(rollout.getId())).withRel("resume")); + body.add(linkTo(methodOn(RolloutRestApi.class).getRolloutGroups(rollout.getId(), Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET), Integer.parseInt(RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT), null, null)).withRel("groups")); return body; @@ -115,8 +116,9 @@ final class RolloutMapper { body.setName(rolloutGroup.getName()); body.setRolloutGroupId(rolloutGroup.getId()); body.setStatus(rolloutGroup.getStatus().toString().toLowerCase()); - body.add(linkTo(methodOn(RolloutResource.class).getRolloutGroup(rolloutGroup.getRollout().getId(), - rolloutGroup.getId())).withRel("self")); + body.add(linkTo( + methodOn(RolloutRestApi.class).getRolloutGroup(rolloutGroup.getRollout().getId(), rolloutGroup.getId())) + .withRel("self")); return body; } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java index d72db72f9..e00d07191 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/RolloutResource.java @@ -27,6 +27,7 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessActi import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.RolloutRestApi; import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutPagedList; import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutResponseBody; import org.eclipse.hawkbit.rest.resource.model.rollout.RolloutRestRequestBody; @@ -40,13 +41,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -54,8 +50,9 @@ import org.springframework.web.bind.annotation.RestController; * */ @RestController -@RequestMapping(RestConstants.ROLLOUT_V1_REQUEST_MAPPING) -public class RolloutResource { +public class RolloutResource implements RolloutRestApi { + + private static final String DOES_NOT_EXIST = "} does not exist"; @Autowired private RolloutManagement rolloutManagement; @@ -66,31 +63,9 @@ public class RolloutResource { @Autowired private DistributionSetManagement distributionSetManagement; - /** - * Handles the GET request of retrieving all rollouts. - * - * @param pagingOffsetParam - * the offset of list of rollouts for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a list of all rollouts for a defined or default page request with - * status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getRollouts( - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getRollouts(final int pagingOffsetParam, final int pagingLimitParam, + final String sortParam, final String rsqlParam) { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -100,50 +75,28 @@ public class RolloutResource { final Page findModulesAll; if (rsqlParam != null) { - findModulesAll = rolloutManagement + findModulesAll = this.rolloutManagement .findAllWithDetailedStatusByPredicate(RSQLUtility.parse(rsqlParam, RolloutFields.class), pageable); } else { - findModulesAll = rolloutManagement.findAll(pageable); + findModulesAll = this.rolloutManagement.findAll(pageable); } final List rest = RolloutMapper.toResponseRollout(findModulesAll.getContent()); return new ResponseEntity<>(new RolloutPagedList(rest, findModulesAll.getTotalElements()), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single rollout. - * - * @param rolloutId - * the ID of the rollout to retrieve - * @return a single rollout with status OK. - * @throws EntityNotFoundException - * in case no rollout with the given {@code rolloutId} exists. - */ - @RequestMapping(value = "/{rolloutId}", method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE, - "application/hal+json" }) - public ResponseEntity getRollout(@PathVariable("rolloutId") final Long rolloutId) { + @Override + public ResponseEntity getRollout(final Long rolloutId) { final Rollout findRolloutById = findRolloutOrThrowException(rolloutId); return new ResponseEntity<>(RolloutMapper.toResponseRollout(findRolloutById), HttpStatus.OK); } - /** - * Handles the POST request for creating rollout. - * - * @param rollout - * the rollout body to be created. - * @return In case rollout could successful created the ResponseEntity with - * status code 201 with the successfully created rollout. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - * @throws EntityNotFoundException - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity create(@RequestBody final RolloutRestRequestBody rolloutRequestBody) { // first check the given RSQL query if it's well formed, otherwise and // exception is thrown - RSQLUtility.isValid(rolloutRequestBody.getTargetFilterQuery()); + RSQLUtility.parse(rolloutRequestBody.getTargetFilterQuery(), TargetFields.class); final DistributionSet distributionSet = findDistributionSetOrThrowException(rolloutRequestBody); @@ -181,7 +134,7 @@ public class RolloutResource { .successCondition(successCondition, successConditionExpr) .successAction(successAction, successActionExpr).errorCondition(errorCondition, errorConditionExpr) .errorAction(errorAction, errorActionExpr).build(); - final Rollout rollout = rolloutManagement.createRollout( + final Rollout rollout = this.rolloutManagement.createRollout( RolloutMapper.fromRequest(rolloutRequestBody, distributionSet, rolloutRequestBody.getTargetFilterQuery()), rolloutRequestBody.getAmountGroups(), rolloutGroupConditions); @@ -189,97 +142,34 @@ public class RolloutResource { return ResponseEntity.status(HttpStatus.CREATED).body(RolloutMapper.toResponseRollout(rollout)); } - /** - * Handles the POST request for starting a rollout. - * - * @param rolloutId - * the ID of the rollout to be started. - * @return OK response (200) if rollout could be started. In case of any - * exception the corresponding errors occur. - * @throws EntityNotFoundException - * @see RolloutManagement#startRollout(Rollout) - * @see ResponseExceptionHandler - */ - @RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/start", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity start(@PathVariable("rolloutId") final Long rolloutId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_ASYNC, defaultValue = "false") final boolean startAsync) { + @Override + public ResponseEntity start(final Long rolloutId, final boolean startAsync) { final Rollout rollout = findRolloutOrThrowException(rolloutId); if (startAsync) { - rolloutManagement.startRolloutAsync(rollout); + this.rolloutManagement.startRolloutAsync(rollout); } else { - rolloutManagement.startRollout(rollout); + this.rolloutManagement.startRollout(rollout); } return ResponseEntity.ok().build(); } - /** - * Handles the POST request for pausing a rollout. - * - * @param rolloutId - * the ID of the rollout to be paused. - * @return OK response (200) if rollout could be paused. In case of any - * exception the corresponding errors occur. - * @throws EntityNotFoundException - * @see RolloutManagement#pauseRollout(Rollout) - * @see ResponseExceptionHandler - */ - @RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/pause", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity pause(@PathVariable("rolloutId") final Long rolloutId) { + @Override + public ResponseEntity pause(final Long rolloutId) { final Rollout rollout = findRolloutOrThrowException(rolloutId); - rolloutManagement.pauseRollout(rollout); + this.rolloutManagement.pauseRollout(rollout); return ResponseEntity.ok().build(); } - /** - * Handles the POST request for resuming a rollout. - * - * @param rolloutId - * the ID of the rollout to be resumed. - * @return OK response (200) if rollout could be resumed. In case of any - * exception the corresponding errors occur. - * @throws EntityNotFoundException - * @see RolloutManagement#resumeRollout(Rollout) - * @see ResponseExceptionHandler - */ - @RequestMapping(method = RequestMethod.POST, value = "/{rolloutId}/resume", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity resume(@PathVariable("rolloutId") final Long rolloutId) { + @Override + public ResponseEntity resume(final Long rolloutId) { final Rollout rollout = findRolloutOrThrowException(rolloutId); - rolloutManagement.resumeRollout(rollout); + this.rolloutManagement.resumeRollout(rollout); return ResponseEntity.ok().build(); } - /** - * Handles the GET request of retrieving all rollout groups referred to a - * rollout. - * - * @param pagingOffsetParam - * the offset of list of rollout groups for pagination, might not - * be present in the rest request then default value will be - * applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a list of all rollout groups referred to a rollout for a defined - * or default page request with status OK. The response is always - * paged. In any failure the JsonResponseExceptionHandler is - * handling the response. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getRolloutGroups(@PathVariable("rolloutId") final Long rolloutId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getRolloutGroups(final Long rolloutId, final int pagingOffsetParam, + final int pagingLimitParam, final String sortParam, final String rsqlParam) { final Rollout rollout = findRolloutOrThrowException(rolloutId); final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); @@ -290,10 +180,10 @@ public class RolloutResource { final Page findRolloutGroupsAll; if (rsqlParam != null) { - findRolloutGroupsAll = rolloutGroupManagement.findRolloutGroupsByPredicate(rollout, + findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsByPredicate(rollout, RSQLUtility.parse(rsqlParam, RolloutGroupFields.class), pageable); } else { - findRolloutGroupsAll = rolloutGroupManagement.findRolloutGroupsByRolloutId(rolloutId, pageable); + findRolloutGroupsAll = this.rolloutGroupManagement.findRolloutGroupsByRolloutId(rolloutId, pageable); } final List rest = RolloutMapper @@ -302,56 +192,16 @@ public class RolloutResource { HttpStatus.OK); } - /** - * Handles the GET request for retrieving a single rollout group. - * - * @param rolloutId - * the rolloutId to retrieve the group from - * @param groupId - * the groupId to retrieve the rollout group - * @return the OK response containing the {@link RolloutGroupResponseBody} - * @throws EntityNotFoundException - */ - @RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getRolloutGroup(@PathVariable("rolloutId") final Long rolloutId, - @PathVariable("groupId") final Long groupId) { + @Override + public ResponseEntity getRolloutGroup(final Long rolloutId, final Long groupId) { findRolloutOrThrowException(rolloutId); final RolloutGroup rolloutGroup = findRolloutGroupOrThrowException(groupId); return ResponseEntity.ok(RolloutMapper.toResponseRolloutGroup(rolloutGroup)); } - /** - * Retrieves all targets related to a specific rollout group. - * - * @param rolloutId - * the ID of the rollout - * @param groupId - * the ID of the rollout group - * @param pagingOffsetParam - * the offset of list of rollout groups for pagination, might not - * be present in the rest request then default value will be - * applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a paged list of targets related to a specific rollout and rollout - * group. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{rolloutId}/deploygroups/{groupId}/targets", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) - public ResponseEntity getRolloutGroupTargets(@PathVariable("rolloutId") final Long rolloutId, - @PathVariable("groupId") final Long groupId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getRolloutGroupTargets(final Long rolloutId, final Long groupId, + final int pagingOffsetParam, final int pagingLimitParam, final String sortParam, final String rsqlParam) { findRolloutOrThrowException(rolloutId); final RolloutGroup rolloutGroup = findRolloutGroupOrThrowException(groupId); @@ -364,10 +214,11 @@ public class RolloutResource { final Page rolloutGroupTargets; if (rsqlParam != null) { final Specification rsqlSpecification = RSQLUtility.parse(rsqlParam, TargetFields.class); - rolloutGroupTargets = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, rsqlSpecification, + rolloutGroupTargets = this.rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, rsqlSpecification, pageable); } else { - final Page pageTargets = rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, pageable); + final Page pageTargets = this.rolloutGroupManagement.findRolloutGroupTargets(rolloutGroup, + pageable); rolloutGroupTargets = pageTargets; } final List rest = TargetMapper.toResponse(rolloutGroupTargets.getContent()); @@ -375,27 +226,27 @@ public class RolloutResource { } private Rollout findRolloutOrThrowException(final Long rolloutId) { - final Rollout rollout = rolloutManagement.findRolloutWithDetailedStatus(rolloutId); + final Rollout rollout = this.rolloutManagement.findRolloutWithDetailedStatus(rolloutId); if (rollout == null) { - throw new EntityNotFoundException("Rollout with Id {" + rolloutId + "} does not exist"); + throw new EntityNotFoundException("Rollout with Id {" + rolloutId + DOES_NOT_EXIST); } return rollout; } private RolloutGroup findRolloutGroupOrThrowException(final Long rolloutGroupId) { - final RolloutGroup rolloutGroup = rolloutGroupManagement.findRolloutGroupById(rolloutGroupId); + final RolloutGroup rolloutGroup = this.rolloutGroupManagement.findRolloutGroupById(rolloutGroupId); if (rolloutGroup == null) { - throw new EntityNotFoundException("Group with Id {" + rolloutGroupId + "} does not exist"); + throw new EntityNotFoundException("Group with Id {" + rolloutGroupId + DOES_NOT_EXIST); } return rolloutGroup; } private DistributionSet findDistributionSetOrThrowException(final RolloutRestRequestBody rolloutRequestBody) { - final DistributionSet ds = distributionSetManagement + final DistributionSet ds = this.distributionSetManagement .findDistributionSetById(rolloutRequestBody.getDistributionSetId()); if (ds == null) { throw new EntityNotFoundException( - "DistributionSet with Id {" + rolloutRequestBody.getDistributionSetId() + "} does not exist"); + "DistributionSet with Id {" + rolloutRequestBody.getDistributionSetId() + DOES_NOT_EXIST); } return ds; } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleMapper.java index 947c216dd..1a3ce603f 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleMapper.java @@ -21,6 +21,8 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleRestAPI; +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi; import org.eclipse.hawkbit.rest.resource.model.MetadataRest; import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactHash; import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest; @@ -142,13 +144,13 @@ public final class SoftwareModuleMapper { response.setType(baseSofwareModule.getType().getKey()); response.setVendor(baseSofwareModule.getVendor()); - response.add(linkTo(methodOn(SoftwareModuleResource.class).getArtifacts(response.getModuleId())) + response.add(linkTo(methodOn(SoftwareModuleRestAPI.class).getArtifacts(response.getModuleId())) .withRel(RestConstants.SOFTWAREMODULE_V1_ARTIFACT)); - response.add(linkTo(methodOn(SoftwareModuleResource.class).getSoftwareModule(response.getModuleId())) + response.add(linkTo(methodOn(SoftwareModuleRestAPI.class).getSoftwareModule(response.getModuleId())) .withRel("self")); response.add(linkTo( - methodOn(SoftwareModuleTypeResource.class).getSoftwareModuleType(baseSofwareModule.getType().getId())) + methodOn(SoftwareModuleTypeRestApi.class).getSoftwareModuleType(baseSofwareModule.getType().getId())) .withRel(RestConstants.SOFTWAREMODULE_V1_TYPE)); response.add(linkTo(methodOn(SoftwareModuleResource.class).getMetadata(response.getModuleId(), @@ -178,13 +180,13 @@ public final class SoftwareModuleMapper { RestModelMapper.mapBaseToBase(artifactRest, artifact); - artifactRest.add(linkTo(methodOn(SoftwareModuleResource.class).getArtifact(artifact.getSoftwareModule().getId(), + artifactRest.add(linkTo(methodOn(SoftwareModuleRestAPI.class).getArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withRel("self")); if (artifact instanceof LocalArtifact) { - artifactRest.add( - linkTo(methodOn(SoftwareModuleResource.class).downloadArtifact(artifact.getSoftwareModule().getId(), - artifact.getId(), null, null)).withRel("download")); + artifactRest.add(linkTo(methodOn(DownloadArtifactResource.class) + .downloadArtifact(artifact.getSoftwareModule().getId(), artifact.getId(), null, null)) + .withRel("download")); } return artifactRest; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java index 5c60334cd..9ce1a2975 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleResource.java @@ -11,22 +11,17 @@ package org.eclipse.hawkbit.rest.resource; import java.io.IOException; import java.util.List; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SoftwareModuleFields; import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.Artifact; -import org.eclipse.hawkbit.repository.model.LocalArtifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; import org.eclipse.hawkbit.repository.model.SwMetadataCompositeKey; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; -import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleRestAPI; import org.eclipse.hawkbit.rest.resource.model.MetadataRest; import org.eclipse.hawkbit.rest.resource.model.MetadataRestPageList; import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactRest; @@ -44,14 +39,10 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; @@ -59,13 +50,9 @@ import org.springframework.web.multipart.MultipartFile; * REST Resource handling for {@link SoftwareModule} and related * {@link Artifact} CRUD operations. * - * - * - * */ @RestController -@RequestMapping(RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) -public class SoftwareModuleResource { +public class SoftwareModuleResource implements SoftwareModuleRestAPI { private static final Logger LOG = LoggerFactory.getLogger(SoftwareModuleResource.class); @Autowired @@ -74,25 +61,7 @@ public class SoftwareModuleResource { @Autowired private SoftwareManagement softwareManagement; - /** - * Handles POST request for artifact upload. - * - * @param softwareModuleId - * of the parent {@link SoftwareModule} - * @param file - * that has to be uploaded - * @param optionalFileName - * to override {@link MultipartFile#getOriginalFilename()} - * @param md5Sum - * checksum for uploaded content check - * @param sha1Sum - * checksum for uploaded content check - * - * @return {@link ResponseEntity} if status {@link HttpStatus#CREATED} if - * successful - */ - @RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/artifacts", produces = { - "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity uploadArtifact(@PathVariable final Long softwareModuleId, @RequestParam("file") final MultipartFile file, @RequestParam(value = "filename", required = false) final String optionalFileName, @@ -123,19 +92,7 @@ public class SoftwareModuleResource { } - /** - * Handles the GET request of retrieving all meta data of artifacts assigned - * to a software module. - * - * @param softwareModuleId - * of the parent {@link SoftwareModule} - * - * @return {@link ResponseEntity} with status {@link HttpStatus#OK} if - * successful - */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts", produces = { - "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - @ResponseBody + @Override public ResponseEntity getArtifacts(@PathVariable final Long softwareModuleId) { final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); @@ -146,55 +103,49 @@ public class SoftwareModuleResource { * Handles the GET request for downloading an artifact. * * @param softwareModuleId - * of the parent {@link SoftwareModule} + * of the parent SoftwareModule * @param artifactId - * of the related {@link LocalArtifact} + * of the related LocalArtifact * @param servletResponse * of the servlet * @param request * of the client * - * @return {@link ResponseEntity} with status {@link HttpStatus#OK} if - * successful + * @return responseEntity with status ok if successful */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}/download") - @ResponseBody - public ResponseEntity downloadArtifact(@PathVariable final Long softwareModuleId, - @PathVariable final Long artifactId, final HttpServletResponse servletResponse, - final HttpServletRequest request) { - final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); + // @RequestMapping(method = RequestMethod.GET, value = + // RestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + // + "/{softwareModuleId}/artifacts/{artifactId}/download") + // @ResponseBody + // public ResponseEntity downloadArtifact(@PathVariable final Long + // softwareModuleId, + // @PathVariable final Long artifactId, final HttpServletResponse + // servletResponse, + // final HttpServletRequest request) { + // final SoftwareModule module = + // findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); + // + // if (null == module || !module.getLocalArtifact(artifactId).isPresent()) { + // return new ResponseEntity<>(HttpStatus.NOT_FOUND); + // } + // + // final LocalArtifact artifact = module.getLocalArtifact(artifactId).get(); + // final DbArtifact file = + // artifactManagement.loadLocalArtifactBinary(artifact); + // + // final String ifMatch = request.getHeader("If-Match"); + // if (ifMatch != null && + // !RestResourceConversionHelper.matchesHttpHeader(ifMatch, + // artifact.getSha1Hash())) { + // return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED); + // } + // + // return RestResourceConversionHelper.writeFileResponse(artifact, + // servletResponse, request, file); + // + // } - if (null == module || !module.getLocalArtifact(artifactId).isPresent()) { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } - - final LocalArtifact artifact = module.getLocalArtifact(artifactId).get(); - final DbArtifact file = artifactManagement.loadLocalArtifactBinary(artifact); - - final String ifMatch = request.getHeader("If-Match"); - if (ifMatch != null && !RestResourceConversionHelper.matchesHttpHeader(ifMatch, artifact.getSha1Hash())) { - return new ResponseEntity<>(HttpStatus.PRECONDITION_FAILED); - } - - return RestResourceConversionHelper.writeFileResponse(artifact, servletResponse, request, file); - - } - - /** - * Handles the GET request of retrieving a single Artifact meta data - * request. - * - * @param softwareModuleId - * of the parent {@link SoftwareModule} - * @param artifactId - * of the related {@link LocalArtifact} - * - * @return {@link ResponseEntity} with status {@link HttpStatus#OK} if - * successful - */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/artifacts/{artifactId}", produces = { - "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - @ResponseBody + @Override public ResponseEntity getArtifact(@PathVariable final Long softwareModuleId, @PathVariable final Long artifactId) { final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); @@ -203,18 +154,7 @@ public class SoftwareModuleResource { HttpStatus.OK); } - /** - * Handles the DELETE request for a single SoftwareModule within SP. - * - * @param softwareModuleId - * the ID of the module that has the artifact - * @param artifactId - * of the artifact to be deleted - * - * @return status OK if delete as successful. - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/artifacts/{artifactId}") - @ResponseBody + @Override public ResponseEntity deleteArtifact(@PathVariable final Long softwareModuleId, @PathVariable final Long artifactId) { findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, artifactId); @@ -225,27 +165,7 @@ public class SoftwareModuleResource { } - /** - * Handles the GET request of retrieving all softwaremodules within SP. - * - * @param pagingOffsetParam - * the offset of list of modules for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * - * @return a list of all modules for a defined or default page request with - * status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getSoftwareModules( @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @@ -273,38 +193,14 @@ public class SoftwareModuleResource { return new ResponseEntity<>(new SoftwareModulePagedList(rest, countModulesAll), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single software module within SP. - * - * @param softwareModuleId - * the ID of the module to retrieve - * - * @return a single softwareModule with status OK. - * @throws EntityNotFoundException - * in case no with the given {@code softwareModuleId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getSoftwareModule(@PathVariable final Long softwareModuleId) { final SoftwareModule findBaseSoftareModule = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); return new ResponseEntity<>(SoftwareModuleMapper.toResponse(findBaseSoftareModule), HttpStatus.OK); } - /** - * Handles the POST request of creating new softwaremodules within SP. The - * request body must always be a list of modules. The requests is delgating - * to the {@link SoftwareManagement#createSoftwareModule(Iterable)}. - * - * @param softwareModules - * the modules to be created. - * @return In case all modules could successful created the ResponseEntity - * with status code 201 - Created but without ResponseBody. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity createSoftwareModules( @RequestBody final List softwareModules) { LOG.debug("creating {} softwareModules", softwareModules.size()); @@ -316,18 +212,7 @@ public class SoftwareModuleResource { HttpStatus.CREATED); } - /** - * Handles the PUT request of updating a software module within SP. - * {@link SoftwareManagement#createSoftwareModule(Iterable)}. - * - * @param softwareModuleId - * the ID of the software module in the URL - * @param restSoftwareModule - * the modules to be updated. - * @return status OK if update is successful - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity updateSoftwareModule(@PathVariable final Long softwareModuleId, @RequestBody final SoftwareModuleRequestBodyPut restSoftwareModule) { final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); @@ -344,15 +229,7 @@ public class SoftwareModuleResource { return new ResponseEntity<>(SoftwareModuleMapper.toResponse(updateSoftwareModule), HttpStatus.OK); } - /** - * Handles the DELETE request for a single softwaremodule within SP. - * - * @param softwareModuleId - * the ID of the module to retrieve - * @return status OK if delete as sucessfull. - * - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}") + @Override public ResponseEntity deleteSoftwareModule(@PathVariable final Long softwareModuleId) { final SoftwareModule module = findSoftwareModuleWithExceptionIfNotFound(softwareModuleId, null); @@ -361,28 +238,7 @@ public class SoftwareModuleResource { return new ResponseEntity<>(HttpStatus.OK); } - /** - * Gets a paged list of meta data for a software module. - * - * @param softwareModuleId - * the ID of the software module for the meta data - * @param pagingOffsetParam - * the offset of list of meta data for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=key==abc} - * @return status OK if get request is successful with the paged list of - * meta data - */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + @Override public ResponseEntity getMetadata(@PathVariable final Long softwareModuleId, @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @@ -412,18 +268,7 @@ public class SoftwareModuleResource { HttpStatus.OK); } - /** - * Gets a single meta data value for a specific key of a software module. - * - * @param softwareModuleId - * the ID of the software module to get the meta data from - * @param metadataKey - * the key of the meta data entry to retrieve the value from - * @return status OK if get request is successful with the value of the meta - * data - */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = { - MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity getMetadataValue(@PathVariable final Long softwareModuleId, @PathVariable final String metadataKey) { // check if distribution set exists otherwise throw exception @@ -433,18 +278,7 @@ public class SoftwareModuleResource { return ResponseEntity. ok(SoftwareModuleMapper.toResponseSwMetadata(findOne)); } - /** - * Updates a single meta data value of a software module. - * - * @param softwareModuleId - * the ID of the software module to update the meta data entry - * @param metadataKey - * the key of the meta data to update the value - * @return status OK if the update request is successful and the updated - * meta data result - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleId}/metadata/{metadataKey}", produces = { - MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + @Override public ResponseEntity updateMetadata(@PathVariable final Long softwareModuleId, @PathVariable final String metadataKey, @RequestBody final MetadataRest metadata) { // check if software module exists otherwise throw exception immediately @@ -454,16 +288,7 @@ public class SoftwareModuleResource { return ResponseEntity.ok(SoftwareModuleMapper.toResponseSwMetadata(updated)); } - /** - * Deletes a single meta data entry from the software module. - * - * @param softwareModuleId - * the ID of the software module to delete the meta data entry - * @param metadataKey - * the key of the meta data to delete - * @return status OK if the delete request is successful - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleId}/metadata/{metadataKey}") + @Override public ResponseEntity deleteMetadata(@PathVariable final Long softwareModuleId, @PathVariable final String metadataKey) { // check if software module exists otherwise throw exception immediately @@ -472,19 +297,7 @@ public class SoftwareModuleResource { return ResponseEntity.ok().build(); } - /** - * Creates a list of meta data for a specific software module. - * - * @param softwareModuleId - * the ID of the distribution set to create meta data for - * @param metadataRest - * the list of meta data entries to create - * @return status created if post request is successful with the value of - * the created meta data - */ - @RequestMapping(method = RequestMethod.POST, value = "/{softwareModuleId}/metadata", consumes = { - MediaType.APPLICATION_JSON_VALUE, - "application/hal+json" }, produces = { MediaType.APPLICATION_JSON_VALUE, "application/hal+json" }) + @Override public ResponseEntity> createMetadata(@PathVariable final Long softwareModuleId, @RequestBody final List metadataRest) { // check if software module exists otherwise throw exception immediately diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeMapper.java index d187aa63a..5a05133b2 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeMapper.java @@ -16,6 +16,7 @@ import java.util.Collection; import java.util.List; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi; import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost; import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRest; import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypesRest; @@ -73,7 +74,7 @@ final class SoftwareModuleTypeMapper { result.setMaxAssignments(type.getMaxAssignments()); result.setModuleId(type.getId()); - result.add(linkTo(methodOn(SoftwareModuleTypeResource.class).getSoftwareModuleType(result.getModuleId())) + result.add(linkTo(methodOn(SoftwareModuleTypeRestApi.class).getSoftwareModuleType(result.getModuleId())) .withRel("self")); return result; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java index 621efc690..c989bf6ad 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java @@ -10,8 +10,6 @@ package org.eclipse.hawkbit.rest.resource; import java.util.List; -import javax.persistence.EntityManager; - import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; @@ -19,6 +17,7 @@ import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.SoftwareModuleTypeRestApi; import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypePagedList; import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPost; import org.eclipse.hawkbit.rest.resource.model.softwaremoduletype.SoftwareModuleTypeRequestBodyPut; @@ -30,59 +29,22 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * REST Resource handling for {@link SoftwareModule} and related * {@link Artifact} CRUD operations. * - * - * - * */ @RestController -@RequestMapping(RestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) -public class SoftwareModuleTypeResource { +public class SoftwareModuleTypeResource implements SoftwareModuleTypeRestApi { @Autowired private SoftwareManagement softwareManagement; - @Autowired - private EntityManager entityManager; - - /** - * Handles the GET request of retrieving all {@link SoftwareModuleType}s - * within SP. - * - * @param pagingOffsetParam - * the offset of list of modules for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * - * @return a list of all module type for a defined or default page request - * with status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getTypes( - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getTypes(final int pagingOffsetParam, final int pagingLimitParam, + final String sortParam, final String rsqlParam) { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -93,12 +55,12 @@ public class SoftwareModuleTypeResource { final Slice findModuleTypessAll; Long countModulesAll; if (rsqlParam != null) { - findModuleTypessAll = softwareManagement.findSoftwareModuleTypesByPredicate( + findModuleTypessAll = this.softwareManagement.findSoftwareModuleTypesByPredicate( RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class), pageable); countModulesAll = ((Page) findModuleTypessAll).getTotalElements(); } else { - findModuleTypessAll = softwareManagement.findSoftwareModuleTypesAll(pageable); - countModulesAll = softwareManagement.countSoftwareModuleTypesAll(); + findModuleTypessAll = this.softwareManagement.findSoftwareModuleTypesAll(pageable); + countModulesAll = this.softwareManagement.countSoftwareModuleTypesAll(); } final List rest = SoftwareModuleTypeMapper @@ -106,56 +68,25 @@ public class SoftwareModuleTypeResource { return new ResponseEntity<>(new SoftwareModuleTypePagedList(rest, countModulesAll), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single software module type - * within SP. - * - * @param softwareModuleTypeId - * the ID of the module type to retrieve - * - * @return a single softwareModule with status OK. - * @throws EntityNotFoundException - * in case no with the given {@code softwareModuleId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{softwareModuleTypeId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getSoftwareModuleType(@PathVariable final Long softwareModuleTypeId) { + @Override + public ResponseEntity getSoftwareModuleType(final Long softwareModuleTypeId) { final SoftwareModuleType foundType = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(foundType), HttpStatus.OK); } - /** - * Handles the DELETE request for a single software module type within SP. - * - * @param softwareModuleTypeId - * the ID of the module to retrieve - * @return status OK if delete as sucessfull. - * - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{softwareModuleTypeId}") - public ResponseEntity deleteSoftwareModuleType(@PathVariable final Long softwareModuleTypeId) { + @Override + public ResponseEntity deleteSoftwareModuleType(final Long softwareModuleTypeId) { final SoftwareModuleType module = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); - softwareManagement.deleteSoftwareModuleType(module); + this.softwareManagement.deleteSoftwareModuleType(module); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the PUT request of updating a software module type within SP. - * - * @param softwareModuleTypeId - * the ID of the software module in the URL - * @param restSoftwareModuleType - * the module type to be updated. - * @return status OK if update is successful - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{softwareModuleTypeId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity updateSoftwareModuleType( - @PathVariable final Long softwareModuleTypeId, - @RequestBody final SoftwareModuleTypeRequestBodyPut restSoftwareModuleType) { + @Override + public ResponseEntity updateSoftwareModuleType(final Long softwareModuleTypeId, + final SoftwareModuleTypeRequestBodyPut restSoftwareModuleType) { final SoftwareModuleType type = findSoftwareModuleTypeWithExceptionIfNotFound(softwareModuleTypeId); // only description can be modified @@ -163,27 +94,15 @@ public class SoftwareModuleTypeResource { type.setDescription(restSoftwareModuleType.getDescription()); } - final SoftwareModuleType updatedSoftwareModuleType = softwareManagement.updateSoftwareModuleType(type); + final SoftwareModuleType updatedSoftwareModuleType = this.softwareManagement.updateSoftwareModuleType(type); return new ResponseEntity<>(SoftwareModuleTypeMapper.toResponse(updatedSoftwareModuleType), HttpStatus.OK); } - /** - * Handles the POST request of creating new {@link SoftwareModuleType}s - * within SP. The request body must always be a list of types. - * - * @param softwareModuleTypes - * the modules to be created. - * @return In case all modules could successful created the ResponseEntity - * with status code 201 - Created but without ResponseBody. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity createSoftwareModuleTypes( - @RequestBody final List softwareModuleTypes) { + final List softwareModuleTypes) { - final List createdSoftwareModules = softwareManagement + final List createdSoftwareModules = this.softwareManagement .createSoftwareModuleTypes(SoftwareModuleTypeMapper.smFromRequest(softwareModuleTypes)); return new ResponseEntity<>(SoftwareModuleTypeMapper.toTypesResponse(createdSoftwareModules), @@ -191,7 +110,7 @@ public class SoftwareModuleTypeResource { } private SoftwareModuleType findSoftwareModuleTypeWithExceptionIfNotFound(final Long softwareModuleTypeId) { - final SoftwareModuleType module = softwareManagement.findSoftwareModuleTypeById(softwareModuleTypeId); + final SoftwareModuleType module = this.softwareManagement.findSoftwareModuleTypeById(softwareModuleTypeId); if (module == null) { throw new EntityNotFoundException( "SoftwareModuleType with Id {" + softwareModuleTypeId + "} does not exist"); diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TagMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TagMapper.java index 80a06ab2d..b5e84abe8 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TagMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TagMapper.java @@ -17,6 +17,8 @@ import java.util.List; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetTagRestApi; +import org.eclipse.hawkbit.rest.resource.api.TargetTagRestApi; import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; import org.eclipse.hawkbit.rest.resource.model.tag.TagRest; import org.eclipse.hawkbit.rest.resource.model.tag.TagsRest; @@ -53,9 +55,9 @@ final class TagMapper { mapTag(response, targetTag); - response.add(linkTo(methodOn(TargetTagResource.class).getTargetTag(targetTag.getId())).withRel("self")); + response.add(linkTo(methodOn(TargetTagRestApi.class).getTargetTag(targetTag.getId())).withRel("self")); - response.add(linkTo(methodOn(TargetTagResource.class).getAssignedTargets(targetTag.getId())) + response.add(linkTo(methodOn(TargetTagRestApi.class).getAssignedTargets(targetTag.getId())) .withRel("assignedTargets")); return response; @@ -83,12 +85,11 @@ final class TagMapper { mapTag(response, distributionSetTag); - response.add( - linkTo(methodOn(DistributionSetTagResource.class).getDistributionSetTag(distributionSetTag.getId())) - .withRel("self")); + response.add(linkTo(methodOn(DistributionSetTagRestApi.class).getDistributionSetTag(distributionSetTag.getId())) + .withRel("self")); response.add(linkTo( - methodOn(DistributionSetTagResource.class).getAssignedDistributionSets(distributionSetTag.getId())) + methodOn(DistributionSetTagRestApi.class).getAssignedDistributionSets(distributionSetTag.getId())) .withRel("assignedDistributionSets")); return response; diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetMapper.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetMapper.java index a79e136cb..4f6ddafb8 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetMapper.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetMapper.java @@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo.PollStatus; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.rest.resource.api.TargetRestApi; import org.eclipse.hawkbit.rest.resource.model.PollStatusRest; import org.eclipse.hawkbit.rest.resource.model.action.ActionRest; import org.eclipse.hawkbit.rest.resource.model.action.ActionStatusRest; @@ -45,18 +46,18 @@ final public class TargetMapper { /** * Add links to a target response. - * + * * @param response * the target response */ public static void addTargetLinks(final TargetRest response) { - response.add(linkTo(methodOn(TargetResource.class).getAssignedDistributionSet(response.getControllerId())) + response.add(linkTo(methodOn(TargetRestApi.class).getAssignedDistributionSet(response.getControllerId())) .withRel(RestConstants.TARGET_V1_ASSIGNED_DISTRIBUTION_SET)); - response.add(linkTo(methodOn(TargetResource.class).getInstalledDistributionSet(response.getControllerId())) + response.add(linkTo(methodOn(TargetRestApi.class).getInstalledDistributionSet(response.getControllerId())) .withRel(RestConstants.TARGET_V1_INSTALLED_DISTRIBUTION_SET)); - response.add(linkTo(methodOn(TargetResource.class).getAttributes(response.getControllerId())) + response.add(linkTo(methodOn(TargetRestApi.class).getAttributes(response.getControllerId())) .withRel(RestConstants.TARGET_V1_ATTRIBUTES)); - response.add(linkTo(methodOn(TargetResource.class).getActionHistory(response.getControllerId(), 0, + response.add(linkTo(methodOn(TargetRestApi.class).getActionHistory(response.getControllerId(), 0, RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionFields.ID.getFieldName() + ":" + SortDirection.DESC, null)) .withRel(RestConstants.TARGET_V1_ACTIONS)); @@ -64,7 +65,7 @@ final public class TargetMapper { /** * Add the pollstatus to a target response. - * + * * @param target * the target * @param targetRest @@ -85,7 +86,7 @@ final public class TargetMapper { /** * Create a response which includes links and pollstatus for all targets. - * + * * @param targets * the targets * @return the response @@ -105,7 +106,7 @@ final public class TargetMapper { /** * Create a response for targets. - * + * * @param targets * list of targets * @return the response @@ -123,7 +124,7 @@ final public class TargetMapper { /** * Create a response for target. - * + * * @param target * the target * @return the response @@ -163,7 +164,7 @@ final public class TargetMapper { targetRest.setInstalledAt(installationDate); } - targetRest.add(linkTo(methodOn(TargetResource.class).getTarget(target.getControllerId())).withRel("self")); + targetRest.add(linkTo(methodOn(TargetRestApi.class).getTarget(target.getControllerId())).withRel("self")); return targetRest; } @@ -210,7 +211,7 @@ final public class TargetMapper { RestModelMapper.mapBaseToBase(result, action); - result.add(linkTo(methodOn(TargetResource.class).getAction(targetId, action.getId())).withRel("self")); + result.add(linkTo(methodOn(TargetRestApi.class).getAction(targetId, action.getId())).withRel("self")); return result; } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java index f50111db8..01f018327 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java @@ -20,13 +20,14 @@ import org.eclipse.hawkbit.repository.ActionStatusFields; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.ActionStatus; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.DistributionSetRestApi; +import org.eclipse.hawkbit.rest.resource.api.TargetRestApi; import org.eclipse.hawkbit.rest.resource.helper.RestResourceConversionHelper; import org.eclipse.hawkbit.rest.resource.model.action.ActionPagedList; import org.eclipse.hawkbit.rest.resource.model.action.ActionRest; @@ -47,25 +48,15 @@ import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.data.jpa.domain.Specification; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** * REST Resource handling target CRUD operations. - * - * - * - * */ @RestController -@RequestMapping(RestConstants.TARGET_V1_REQUEST_MAPPING) -public class TargetResource { +public class TargetResource implements TargetRestApi { private static final Logger LOG = LoggerFactory.getLogger(TargetResource.class); @Autowired @@ -74,18 +65,8 @@ public class TargetResource { @Autowired private DeploymentManagement deploymentManagement; - /** - * Handles the GET request of retrieving a single target within SP. - * - * @param targetId - * the ID of the target to retrieve - * @return a single target with status OK. - * @throws EntityNotFoundException - * in case no target with the given {@code targetId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getTarget(@PathVariable final String targetId) { + @Override + public ResponseEntity getTarget(final String targetId) { final Target findTarget = findTargetWithExceptionIfNotFound(targetId); // to single response include poll status final TargetRest response = TargetMapper.toResponse(findTarget); @@ -95,31 +76,9 @@ public class TargetResource { return new ResponseEntity<>(response, HttpStatus.OK); } - /** - * Handles the GET request of retrieving all targets within SP. - * - * @param pagingOffsetParam - * the offset of list of targets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a list of all targets for a defined or default page request with - * status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getTargets( - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getTargets(final int pagingOffsetParam, final int pagingLimitParam, + final String sortParam, final String rsqlParam) { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -129,58 +88,29 @@ public class TargetResource { final Slice findTargetsAll; final Long countTargetsAll; if (rsqlParam != null) { - final Page findTargetPage = targetManagement + final Page findTargetPage = this.targetManagement .findTargetsAll(RSQLUtility.parse(rsqlParam, TargetFields.class), pageable); countTargetsAll = findTargetPage.getTotalElements(); findTargetsAll = findTargetPage; } else { - findTargetsAll = targetManagement.findTargetsAll(pageable); - countTargetsAll = targetManagement.countTargetsAll(); + findTargetsAll = this.targetManagement.findTargetsAll(pageable); + countTargetsAll = this.targetManagement.countTargetsAll(); } final List rest = TargetMapper.toResponse(findTargetsAll.getContent()); return new ResponseEntity<>(new TargetPagedList(rest, countTargetsAll), HttpStatus.OK); } - /** - * Handles the POST request of creating new targets within SP. The request - * body must always be a list of targets. The requests is delegating to the - * {@link TargetManagement#createTarget(Iterable)}. - * - * @param targets - * the targets to be created. - * @return In case all targets could successful created the ResponseEntity - * with status code 201 with a list of successfully created - * entities. In any failure the JsonResponseExceptionHandler is - * handling the response. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity createTargets(@RequestBody final List targets) { + @Override + public ResponseEntity createTargets(final List targets) { LOG.debug("creating {} targets", targets.size()); - final Iterable createdTargets = targetManagement.createTargets(TargetMapper.fromRequest(targets)); + final Iterable createdTargets = this.targetManagement.createTargets(TargetMapper.fromRequest(targets)); LOG.debug("{} targets created, return status {}", targets.size(), HttpStatus.CREATED); return new ResponseEntity<>(TargetMapper.toResponse(createdTargets), HttpStatus.CREATED); } - /** - * Handles the PUT request of updating a target within SP. The ID is within - * the URL path of the request. A given ID in the request body is ignored. - * It's not possible to set fields to {@code null} values. - * - * @param targetId - * the path parameter which contains the ID of the target - * @param targetRest - * the request body which contains the fields which should be - * updated, fields which are not given are ignored for the - * udpate. - * @return the updated target response which contains all fields also fields - * which have not updated - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{targetId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity updateTarget(@PathVariable final String targetId, - @RequestBody final TargetRequestBody targetRest) { + @Override + public ResponseEntity updateTarget(final String targetId, final TargetRequestBody targetRest) { final Target existingTarget = findTargetWithExceptionIfNotFound(targetId); LOG.debug("updating target {}", existingTarget.getId()); if (targetRest.getDescription() != null) { @@ -189,42 +119,21 @@ public class TargetResource { if (targetRest.getName() != null) { existingTarget.setName(targetRest.getName()); } - final Target updateTarget = targetManagement.updateTarget(existingTarget); + final Target updateTarget = this.targetManagement.updateTarget(existingTarget); return new ResponseEntity<>(TargetMapper.toResponse(updateTarget), HttpStatus.OK); } - /** - * Handles the DELETE request of deleting a target within SP. - * - * @param targetId - * the ID of the target to be deleted - * @return If the given targetId could exists and could be deleted Http OK. - * In any failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity deleteTarget(@PathVariable final String targetId) { + @Override + public ResponseEntity deleteTarget(final String targetId) { final Target target = findTargetWithExceptionIfNotFound(targetId); - targetManagement.deleteTargets(target.getId()); + this.targetManagement.deleteTargets(target.getId()); LOG.debug("{} target deleted, return status {}", targetId, HttpStatus.OK); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the GET request of retrieving the attributes of a specific - * target. - * - * @param targetId - * the ID of the target to retrieve the attributes. - * @return the target attributes as map response with status OK - * @throws EntityNotFoundException - * in case no target with the given {@code targetId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/attributes", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getAttributes(@PathVariable final String targetId) { + @Override + public ResponseEntity getAttributes(final String targetId) { final Target foundTarget = findTargetWithExceptionIfNotFound(targetId); final Map controllerAttributes = foundTarget.getTargetInfo().getControllerAttributes(); if (controllerAttributes.isEmpty()) { @@ -237,36 +146,9 @@ public class TargetResource { return new ResponseEntity<>(result, HttpStatus.OK); } - /** - * Handles the GET request of retrieving the {@link Action}s of a specific - * target. - * - * @param targetId - * to load actions for - * @param pagingOffsetParam - * the offset of list of targets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=status==pending} - * @return a list of all {@link Action}s for a defined or default page - * request with status OK. The response is always paged. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getActionHistory(@PathVariable final String targetId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getActionHistory(final String targetId, final int pagingOffsetParam, + final int pagingLimitParam, final String sortParam, final String rsqlParam) { final Target foundTarget = findTargetWithExceptionIfNotFound(targetId); @@ -279,11 +161,11 @@ public class TargetResource { final Long totalActionCount; if (rsqlParam != null) { final Specification parse = RSQLUtility.parse(rsqlParam, ActionFields.class); - activeActions = deploymentManagement.findActionsByTarget(parse, foundTarget, pageable); - totalActionCount = deploymentManagement.countActionsByTarget(parse, foundTarget); + activeActions = this.deploymentManagement.findActionsByTarget(parse, foundTarget, pageable); + totalActionCount = this.deploymentManagement.countActionsByTarget(parse, foundTarget); } else { - activeActions = deploymentManagement.findActionsByTarget(foundTarget, pageable); - totalActionCount = deploymentManagement.countActionsByTarget(foundTarget); + activeActions = this.deploymentManagement.findActionsByTarget(foundTarget, pageable); + totalActionCount = this.deploymentManagement.countActionsByTarget(foundTarget); } return new ResponseEntity<>( @@ -291,20 +173,8 @@ public class TargetResource { HttpStatus.OK); } - /** - * Handles the GET request of retrieving a specific {@link Action}s of a - * specific {@link Target}. - * - * @param targetId - * to load the action for - * @param actionId - * to load - * @return the action - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}", produces = { - "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getAction(@PathVariable final String targetId, - @PathVariable final Long actionId) { + @Override + public ResponseEntity getAction(final String targetId, final Long actionId) { final Target target = findTargetWithExceptionIfNotFound(targetId); final Action action = findActionWithExceptionIfNotFound(actionId); @@ -317,14 +187,14 @@ public class TargetResource { if (!action.isCancelingOrCanceled()) { result.add(linkTo( - methodOn(DistributionSetResource.class).getDistributionSet(action.getDistributionSet().getId())) + methodOn(DistributionSetRestApi.class).getDistributionSet(action.getDistributionSet().getId())) .withRel("distributionset")); } else if (action.isCancelingOrCanceled()) { - result.add(linkTo(methodOn(TargetResource.class).getAction(targetId, action.getId())) + result.add(linkTo(methodOn(TargetRestApi.class).getAction(targetId, action.getId())) .withRel(RestConstants.TARGET_V1_CANCELED_ACTION)); } - result.add(linkTo(methodOn(TargetResource.class).getActionStatusList(targetId, action.getId(), 0, + result.add(linkTo(methodOn(TargetRestApi.class).getActionStatusList(targetId, action.getId(), 0, RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionStatusFields.ID.getFieldName() + ":" + SortDirection.DESC)) .withRel(RestConstants.TARGET_V1_ACTION_STATUS)); @@ -332,32 +202,16 @@ public class TargetResource { return new ResponseEntity<>(result, HttpStatus.OK); } - /** - * Handles the DELETE request of canceling an specific {@link Action}s of a - * specific {@link Target}. - * - * @param targetId - * the ID of the target in the URL path parameter - * @param actionId - * the ID of the action in the URL path parameter - * @param force - * optional parameter, which indicates a force cancel - * @return status no content in case cancellation was successful - * @throws CancelActionNotAllowedException - * if the given action is not active and cannot be canceled. - * @throws EntityNotFoundException - * if the target or the action is not found - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{targetId}/actions/{actionId}") - public ResponseEntity cancelAction(@PathVariable final String targetId, @PathVariable final Long actionId, + @Override + public ResponseEntity cancelAction(final String targetId, final Long actionId, @RequestParam(required = false, defaultValue = "false") final boolean force) { final Target target = findTargetWithExceptionIfNotFound(targetId); final Action action = findActionWithExceptionIfNotFound(actionId); if (force) { - deploymentManagement.forceQuitAction(action, target); + this.deploymentManagement.forceQuitAction(action, target); } else { - deploymentManagement.cancelAction(action, target); + this.deploymentManagement.cancelAction(action, target); } // both functions will throw an exception, when action is in wrong // state, which is mapped by ResponseExceptionHandler. @@ -365,35 +219,9 @@ public class TargetResource { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } - /** - * Handles the GET request of retrieving the {@link ActionStatus}s of a - * specific target and action. - * - * @param targetId - * of the the action - * @param actionId - * of the status we are intend to load - * @param pagingOffsetParam - * the offset of list of targets for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @return a list of all {@link ActionStatus}s for a defined or default page - * request with status OK. The response is always paged. In any - * failure the JsonResponseExceptionHandler is handling the - * response. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/actions/{actionId}/status", produces = { - "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getActionStatusList(@PathVariable final String targetId, - @PathVariable final Long actionId, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam) { + @Override + public ResponseEntity getActionStatusList(final String targetId, final Long actionId, + final int pagingOffsetParam, final int pagingLimitParam, final String sortParam) { final Target target = findTargetWithExceptionIfNotFound(targetId); @@ -407,7 +235,7 @@ public class TargetResource { final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); final Sort sorting = PagingUtility.sanitizeActionStatusSortParam(sortParam); - final Page statusList = deploymentManagement.findActionStatusMessagesByActionInDescOrder( + final Page statusList = this.deploymentManagement.findActionStatusMessagesByActionInDescOrder( new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting), action, true); return new ResponseEntity<>( @@ -417,20 +245,8 @@ public class TargetResource { } - /** - * Handles the GET request of retrieving the assigned distribution set of an - * specific target. - * - * @param targetId - * the ID of the target to retrieve the assigned distribution - * @return the assigned distribution set with status OK, if none is assigned - * than {@code null} content (e.g. "{}") - * @throws EntityNotFoundException - * in case no target with the given {@code targetId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/assignedDS", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getAssignedDistributionSet(@PathVariable final String targetId) { + @Override + public ResponseEntity getAssignedDistributionSet(final String targetId) { final Target findTarget = findTargetWithExceptionIfNotFound(targetId); final DistributionSetRest distributionSetRest = DistributionSetMapper .toResponse(findTarget.getAssignedDistributionSet()); @@ -443,28 +259,14 @@ public class TargetResource { return new ResponseEntity<>(distributionSetRest, retStatus); } - /** - * Changes the assigned distribution set of a target. - * - * @param targetId - * of the target to change - * @param dsId - * of the distributionset that is to be assigned - * @return {@link HttpStatus#OK} - * - * @throws EntityNotFoundException - * in case no target with the given {@code targetId} exists. - * - */ - @RequestMapping(method = RequestMethod.POST, value = "/{targetId}/assignedDS", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity postAssignedDistributionSet(@PathVariable final String targetId, - @RequestBody final DistributionSetAssigmentRest dsId) { + @Override + public ResponseEntity postAssignedDistributionSet(final String targetId, + final DistributionSetAssigmentRest dsId) { findTargetWithExceptionIfNotFound(targetId); final ActionType type = (dsId.getType() != null) ? RestResourceConversionHelper.convertActionType(dsId.getType()) : ActionType.FORCED; - final Iterator changed = deploymentManagement + final Iterator changed = this.deploymentManagement .assignDistributionSet(dsId.getId(), type, dsId.getForcetime(), targetId).getAssignedTargets() .iterator(); if (changed.hasNext()) { @@ -477,20 +279,8 @@ public class TargetResource { } - /** - * Handles the GET request of retrieving the installed distribution set of - * an specific target. - * - * @param targetId - * the ID of the target to retrieve - * @return the assigned installed set with status OK, if none is installed - * than {@code null} content (e.g. "{}") - * @throws EntityNotFoundException - * in case no target with the given {@code targetId} exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetId}/installedDS", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getInstalledDistributionSet(@PathVariable final String targetId) { + @Override + public ResponseEntity getInstalledDistributionSet(final String targetId) { final Target findTarget = findTargetWithExceptionIfNotFound(targetId); final DistributionSetRest distributionSetRest = DistributionSetMapper .toResponse(findTarget.getTargetInfo().getInstalledDistributionSet()); @@ -504,7 +294,7 @@ public class TargetResource { } private Target findTargetWithExceptionIfNotFound(final String targetId) { - final Target findTarget = targetManagement.findTargetByControllerID(targetId); + final Target findTarget = this.targetManagement.findTargetByControllerID(targetId); if (findTarget == null) { throw new EntityNotFoundException("Target with Id {" + targetId + "} does not exist"); } @@ -512,7 +302,7 @@ public class TargetResource { } private Action findActionWithExceptionIfNotFound(final Long actionId) { - final Action findAction = deploymentManagement.findAction(actionId); + final Action findAction = this.deploymentManagement.findAction(actionId); if (findAction == null) { throw new EntityNotFoundException("Action with Id {" + actionId + "} does not exist"); } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java index ef10efbad..76209a958 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetTagResource.java @@ -11,8 +11,6 @@ package org.eclipse.hawkbit.rest.resource; import java.util.List; import java.util.stream.Collectors; -import javax.persistence.EntityManager; - import org.eclipse.hawkbit.repository.TagFields; import org.eclipse.hawkbit.repository.TagManagement; import org.eclipse.hawkbit.repository.TargetManagement; @@ -21,6 +19,7 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssigmentResult; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.rest.resource.api.TargetTagRestApi; import org.eclipse.hawkbit.rest.resource.model.tag.AssignedTargetRequestBody; import org.eclipse.hawkbit.rest.resource.model.tag.TagPagedList; import org.eclipse.hawkbit.rest.resource.model.tag.TagRequestBodyPut; @@ -36,13 +35,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; /** @@ -50,10 +44,8 @@ import org.springframework.web.bind.annotation.RestController; * */ @RestController -@RequestMapping(RestConstants.TARGET_TAG_V1_REQUEST_MAPPING) -public class TargetTagResource { +public class TargetTagResource implements TargetTagRestApi { private static final Logger LOG = LoggerFactory.getLogger(TargetTagResource.class); - private static final String TARGET_TAG_TAGERTS_REQUEST_MAPPING = RestConstants.TARGET_TAG_TAGERTS_REQUEST_MAPPING; @Autowired private TagManagement tagManagement; @@ -61,34 +53,9 @@ public class TargetTagResource { @Autowired private TargetManagement targetManagement; - @Autowired - private EntityManager entityManager; - - /** - * Handles the GET request of retrieving all target tags. - * - * @param pagingOffsetParam - * the offset of list of target tags for pagination, might not be - * present in the rest request then default value will be applied - * @param pagingLimitParam - * the limit of the paged request, might not be present in the - * rest request then default value will be applied - * @param sortParam - * the sorting parameter in the request URL, syntax - * {@code field:direction, field:direction} - * @param rsqlParam - * the search parameter in the request URL, syntax - * {@code q=name==abc} - * @return a list of all target tags for a defined or default page request - * with status OK. The response is always paged. In any failure the - * JsonResponseExceptionHandler is handling the response. - */ - @RequestMapping(method = RequestMethod.GET, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getTargetTags( - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = RestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SORTING, required = false) final String sortParam, - @RequestParam(value = RestConstants.REQUEST_PARAMETER_SEARCH, required = false) final String rsqlParam) { + @Override + public ResponseEntity getTargetTags(final int pagingOffsetParam, final int pagingLimitParam, + final String sortParam, final String rsqlParam) { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); @@ -98,11 +65,11 @@ public class TargetTagResource { final Slice findTargetsAll; final Long countTargetsAll; if (rsqlParam == null) { - findTargetsAll = tagManagement.findAllTargetTags(pageable); - countTargetsAll = tagManagement.countTargetTags(); + findTargetsAll = this.tagManagement.findAllTargetTags(pageable); + countTargetsAll = this.tagManagement.countTargetTags(); } else { - final Page findTargetPage = tagManagement + final Page findTargetPage = this.tagManagement .findAllTargetTags(RSQLUtility.parse(rsqlParam, TagFields.class), pageable); countTargetsAll = findTargetPage.getTotalElements(); findTargetsAll = findTargetPage; @@ -113,127 +80,57 @@ public class TargetTagResource { return new ResponseEntity<>(new TagPagedList(rest, countTargetsAll), HttpStatus.OK); } - /** - * Handles the GET request of retrieving a single target tag. - * - * @param targetTagId - * the ID of the target tag to retrieve - * - * @return a single target tag with status OK. - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.GET, value = "/{targetTagId}", produces = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity getTargetTag(@PathVariable final Long targetTagId) { + @Override + public ResponseEntity getTargetTag(final Long targetTagId) { final TargetTag tag = findTargetTagById(targetTagId); return new ResponseEntity<>(TagMapper.toResponse(tag), HttpStatus.OK); } - /** - * Handles the POST request of creating new target tag. The request body - * must always be a list of tags. - * - * @param tags - * the target tags to be created. - * @return In case all modules could successful created the ResponseEntity - * with status code 201 - Created. The Response Body are the created - * target tags but without ResponseBody. - */ - @RequestMapping(method = RequestMethod.POST, consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) + @Override public ResponseEntity createTargetTags(@RequestBody final List tags) { LOG.debug("creating {} target tags", tags.size()); - final List createdTargetTags = tagManagement + final List createdTargetTags = this.tagManagement .createTargetTags(TagMapper.mapTargeTagFromRequest(tags)); return new ResponseEntity<>(TagMapper.toResponse(createdTargetTags), HttpStatus.CREATED); } - /** - * - * Handles the PUT request of updating a single targetr tag. - * - * @param targetTagId - * the ID of the target tag - * @param restTargetTagRest - * the the request body to be updated - * @return status OK if update is successful and the updated target tag. - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.PUT, value = "/{targetTagId}", consumes = { "application/hal+json", - MediaType.APPLICATION_JSON_VALUE }, produces = { "application/hal+json", MediaType.APPLICATION_JSON_VALUE }) - public ResponseEntity updateTagretTag(@PathVariable final Long targetTagId, - @RequestBody final TagRequestBodyPut restTargetTagRest) { + @Override + public ResponseEntity updateTagretTag(final Long targetTagId, final TagRequestBodyPut restTargetTagRest) { LOG.debug("update {} target tag", restTargetTagRest); final TargetTag targetTag = findTargetTagById(targetTagId); TagMapper.updateTag(restTargetTagRest, targetTag); - final TargetTag updateTargetTag = tagManagement.updateTargetTag(targetTag); + final TargetTag updateTargetTag = this.tagManagement.updateTargetTag(targetTag); LOG.debug("target tag updated"); return new ResponseEntity<>(TagMapper.toResponse(updateTargetTag), HttpStatus.OK); } - /** - * Handles the DELETE request for a single target tag. - * - * @param targetTagId - * the ID of the target tag - * @return status OK if delete as successfully. - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - * - */ - @RequestMapping(method = RequestMethod.DELETE, value = "/{targetTagId}") - public ResponseEntity deleteTargetTag(@PathVariable final Long targetTagId) { + @Override + public ResponseEntity deleteTargetTag(final Long targetTagId) { LOG.debug("Delete {} target tag", targetTagId); final TargetTag targetTag = findTargetTagById(targetTagId); - tagManagement.deleteTargetTag(targetTag.getName()); + this.tagManagement.deleteTargetTag(targetTag.getName()); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the GET request of retrieving all assigned targets by the given - * tag id. - * - * @param targetTagId - * the ID of the target tag to retrieve - * - * @return the list of assigned targets. - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.GET, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING) - public ResponseEntity getAssignedTargets(@PathVariable final Long targetTagId) { + @Override + public ResponseEntity getAssignedTargets(final Long targetTagId) { final TargetTag targetTag = findTargetTagById(targetTagId); return new ResponseEntity<>(TargetMapper.toResponseWithLinksAndPollStatus(targetTag.getAssignedToTargets()), HttpStatus.OK); } - /** - * Handles the POST request to toggle the assignment of targets by the given - * tag id. - * - * @param targetTagId - * the ID of the target tag to retrieve - * @param assignedTargetRequestBodies - * list of target ids to be toggled - * - * @return the list of assigned targets and unassigned targets. - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.POST, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/toggleTagAssignment") - public ResponseEntity toggleTagAssignment(@PathVariable final Long targetTagId, - @RequestBody final List assignedTargetRequestBodies) { + @Override + public ResponseEntity toggleTagAssignment(final Long targetTagId, + final List assignedTargetRequestBodies) { LOG.debug("Toggle Target assignment {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId); final TargetTag targetTag = findTargetTagById(targetTagId); - final TargetTagAssigmentResult assigmentResult = targetManagement + final TargetTagAssigmentResult assigmentResult = this.targetManagement .toggleTagAssignment(findTargetControllerIds(assignedTargetRequestBodies), targetTag.getName()); final TargetTagAssigmentResultRest tagAssigmentResultRest = new TargetTagAssigmentResultRest(); @@ -242,71 +139,38 @@ public class TargetTagResource { return new ResponseEntity<>(tagAssigmentResultRest, HttpStatus.OK); } - /** - * Handles the POST request to assign targets to the given tag id. - * - * @param targetTagId - * the ID of the target tag to retrieve - * @param assignedTargetRequestBodies - * list of target ids to be assigned - * - * @return the list of assigned targets. - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.POST, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING) - public ResponseEntity assignTargets(@PathVariable final Long targetTagId, - @RequestBody final List assignedTargetRequestBodies) { + @Override + public ResponseEntity assignTargets(final Long targetTagId, + final List assignedTargetRequestBodies) { LOG.debug("Assign Targets {} for target tag {}", assignedTargetRequestBodies.size(), targetTagId); final TargetTag targetTag = findTargetTagById(targetTagId); - final List assignedTarget = targetManagement + final List assignedTarget = this.targetManagement .assignTag(findTargetControllerIds(assignedTargetRequestBodies), targetTag); return new ResponseEntity<>(TargetMapper.toResponseWithLinksAndPollStatus(assignedTarget), HttpStatus.OK); } - /** - * Handles the DELETE request to unassign all targets from the given tag id. - * - * @param targetTagId - * the ID of the target tag to retrieve - * @return http status code - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.DELETE, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING) - public ResponseEntity unassignTargets(@PathVariable final Long targetTagId) { + @Override + public ResponseEntity unassignTargets(final Long targetTagId) { LOG.debug("Unassign all Targets for target tag {}", targetTagId); final TargetTag targetTag = findTargetTagById(targetTagId); if (targetTag.getAssignedToTargets() == null) { LOG.debug("No assigned targets found"); return new ResponseEntity<>(HttpStatus.OK); } - targetManagement.unAssignAllTargetsByTag(targetTag); + this.targetManagement.unAssignAllTargetsByTag(targetTag); return new ResponseEntity<>(HttpStatus.OK); } - /** - * Handles the DELETE request to unassign one target from the given tag id. - * - * @param targetTagId - * the ID of the target tag - * @param controllerId - * the ID of the target to unassign - * @return http status code - * @throws EntityNotFoundException - * in case the given {@code targetTagId} doesn't exists. - */ - @RequestMapping(method = RequestMethod.DELETE, value = TARGET_TAG_TAGERTS_REQUEST_MAPPING + "/{controllerId}") - public ResponseEntity unassignTarget(@PathVariable final Long targetTagId, - @PathVariable final String controllerId) { + @Override + public ResponseEntity unassignTarget(final Long targetTagId, final String controllerId) { LOG.debug("Unassign target {} for target tag {}", controllerId, targetTagId); final TargetTag targetTag = findTargetTagById(targetTagId); - targetManagement.unAssignTag(controllerId, targetTag); + this.targetManagement.unAssignTag(controllerId, targetTag); return new ResponseEntity<>(HttpStatus.OK); } private TargetTag findTargetTagById(final Long targetTagId) { - final TargetTag tag = tagManagement.findTargetTagById(targetTagId); + final TargetTag tag = this.tagManagement.findTargetTagById(targetTagId); if (tag == null) { throw new EntityNotFoundException("Target Tag with Id {" + targetTagId + "} does not exist"); }