From 4a3a79aa6bca17f7bd6658053bc1eaf79c5c6718 Mon Sep 17 00:00:00 2001 From: Stefan Behl Date: Tue, 28 Mar 2023 07:16:25 +0200 Subject: [PATCH] Migration to Spring Boot 2.7.10 (#1320) * Initial commit * Fix compile breaks * Fix hibernate config * Fix hibernate config * Fix failing tests * Improve logging * Improve logging * Fix Sonar issues * Remove BusProperties * Add BusProperties bean back in * Fix JPA workaround * Fix CVE-2021-22044 * Fix test failures * Fix PR review findings * Fix CVEs * Remove H2 version downgrade, fix schema migration, enable legacy mode * Downgrade Vaadin back to 8.14.3 * Fix EventPublisherHolder * Fix RemoteTenantAwareEvent * Fixed EventPublisherAutoConfiguration * New version of spring-hateoas requires links to be expanded (Mgmt API) * New version of spring-hateoas requires links to be expanded (Mgmt API) * Fix PR review findings * Fix PR review findings * Fix PR review findings * Update README.md * MariaDB Java Client downgrade to maintain compatibility with AWS Aurora * Temporarily disable RSQL test that depends on DB collation type * Upgrade to boot 2.7.10 * Upgrade snakeyaml to 1.33 * Upgrade Spring Security OAuth2 to version 5.7.7 * Remove obsolete exclusion of junit-vintage-engine * Upgrade jackson-bom to 2.14.2 --- .azure-pipelines/integration-tests.yml | 2 +- README.md | 4 +- docs/content/guides/runhawkbit.md | 2 +- .../EventPublisherAutoConfiguration.java | 5 +- .../SecurityManagedConfiguration.java | 2 + .../AmqpMessageDispatcherServiceTest.java | 20 +-- ...ssageDispatcherServiceIntegrationTest.java | 8 +- hawkbit-dmf/hawkbit-dmf-rabbitmq-test/pom.xml | 4 +- .../event/remote/RemoteTenantAwareEvent.java | 5 +- .../model/helper/EventPublisherHolder.java | 9 +- .../hawkbit-repository-jpa/pom.xml | 12 ++ .../repository/jpa/ActionRepository.java | 2 +- .../jpa/JpaControllerManagement.java | 67 +++---- .../jpa/JpaDeploymentManagement.java | 16 +- .../RepositoryApplicationConfiguration.java | 4 +- ...V1_10_1__consolidate_artifact_sha1__H2.sql | 5 +- .../V1_10_3__add_rollout_deleted_flag__H2.sql | 16 +- .../H2/V1_11_0__drop_target_info__H2.sql | 4 +- .../H2/V1_11_2__remove_unused_idexes___H2.sql | 14 +- .../H2/V1_12_0__action_performance___H2.sql | 6 +- .../H2/V1_12_1__missing_non_null___H2.sql | 24 +-- .../V1_12_2__missing_non_null_enum___H2.sql | 6 +- .../H2/V1_7_1__reduce_length_enums___H2.sql | 10 +- .../resources/hawkbit-jpa-defaults.properties | 4 +- .../remote/RemoteTenantAwareEventTest.java | 6 +- .../jpa/ControllerManagementTest.java | 2 +- .../jpa/DeploymentManagementTest.java | 4 +- .../autocleanup/AutoActionCleanupTest.java | 8 +- .../jpa/rsql/RSQLSoftwareModuleFieldTest.java | 13 +- .../test/util/MySqlTestDatabase.java | 2 +- .../rest/api/DdiRootControllerRestApi.java | 163 ++++++++++-------- .../rest/resource/DataConversionHelper.java | 18 +- .../ddi/rest/resource/DdiRootController.java | 3 +- .../rest/resource/DdiDeploymentBaseTest.java | 4 +- .../model/distributionset/MgmtActionId.java | 10 +- .../mgmt/rest/api/MgmtActionRestApi.java | 19 +- .../mgmt/rest/api/MgmtBasicAuthRestApi.java | 6 +- .../rest/api/MgmtDistributionSetRestApi.java | 88 ++++++---- .../api/MgmtDistributionSetTagRestApi.java | 60 ++++--- .../api/MgmtDistributionSetTypeRestApi.java | 47 ++--- .../rest/api/MgmtDownloadArtifactRestApi.java | 8 +- .../mgmt/rest/api/MgmtDownloadRestApi.java | 7 +- .../mgmt/rest/api/MgmtRestConstants.java | 2 +- .../mgmt/rest/api/MgmtRolloutRestApi.java | 63 +++---- .../rest/api/MgmtSoftwareModuleRestApi.java | 64 ++++--- .../api/MgmtSoftwareModuleTypeRestApi.java | 26 +-- .../rest/api/MgmtSystemManagementRestApi.java | 14 +- .../api/MgmtTargetFilterQueryRestApi.java | 31 ++-- .../mgmt/rest/api/MgmtTargetRestApi.java | 99 ++++++----- .../mgmt/rest/api/MgmtTargetTagRestApi.java | 43 +++-- .../mgmt/rest/api/MgmtTargetTypeRestApi.java | 63 +++---- .../rest/api/MgmtTenantManagementRestApi.java | 19 +- .../resource/MgmtDistributionSetMapper.java | 9 +- .../MgmtDistributionSetTypeMapper.java | 6 +- .../mgmt/rest/resource/MgmtRolloutMapper.java | 22 ++- .../resource/MgmtSoftwareModuleMapper.java | 13 +- .../MgmtSoftwareModuleTypeMapper.java | 2 +- .../mgmt/rest/resource/MgmtTagMapper.java | 11 +- .../resource/MgmtTargetFilterQueryMapper.java | 5 +- .../mgmt/rest/resource/MgmtTargetMapper.java | 36 ++-- .../rest/resource/MgmtTargetTypeMapper.java | 19 +- .../resource/MgmtTenantManagementMapper.java | 4 +- .../MgmtDistributionSetTagResourceTest.java | 2 +- .../rest/resource/MgmtTargetResourceTest.java | 4 +- .../resource/MgmtTargetTagResourceTest.java | 2 +- hawkbit-rest/hawkbit-rest-core/pom.xml | 4 +- hawkbit-runtime/docker/README.md | 2 +- hawkbit-runtime/docker/docker-compose.yml | 2 +- .../eclipse/hawkbit/app/ErrorController.java | 2 +- .../resources/application-mysql.properties | 2 +- pom.xml | 44 +++-- 71 files changed, 741 insertions(+), 593 deletions(-) diff --git a/.azure-pipelines/integration-tests.yml b/.azure-pipelines/integration-tests.yml index b9fe187ec..9c812bc4e 100644 --- a/.azure-pipelines/integration-tests.yml +++ b/.azure-pipelines/integration-tests.yml @@ -78,7 +78,7 @@ jobs: displayName: "Setup MYSQL Database docker instance" - template: maven-template.yml parameters: - mavenGoals: "verify -Dspring.jpa.database=MYSQL -Dspring.datasource.driverClassName=org.mariadb.jdbc.Driver -Dspring.datasource.url=jdbc:mysql://localhost:3306/hawkbit -Dspring.datasource.username=root -Dspring.datasource.password=8236472364" + mavenGoals: "verify -Dspring.jpa.database=MYSQL -Dspring.datasource.driverClassName=org.mariadb.jdbc.Driver -Dspring.datasource.url=jdbc:mariadb://localhost:3306/hawkbit -Dspring.datasource.username=root -Dspring.datasource.password=8236472364" - job: dependsOn: JDK_8 condition: succeeded() diff --git a/README.md b/README.md index 5e9bbcf82..696a4ba93 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,9 @@ There are clients outside of the Eclipse IoT eco system as well, e.g.: | --------------------------------- | :----------------------------------------------------: | :-------------------------------------------------------------------------: | :--------------------------------------------------------------: | :----------------------------------------------------------------: | :----------------: | | DDLs maintained by project | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Test dependencies defined | :white_check_mark: | :white_check_mark: | :white_check_mark: | :white_check_mark: | | -| Versions tested | 1.4 | MySQL 5.6/5.7, AWS Aurora | MS SQL Server 2017/2019 | PostgreSQL 12/13 | DB2 Server v11.1 | +| Versions tested | 2.1 | MySQL 8.0.23, AWS Aurora | MS SQL Server 2017/2019 | PostgreSQL 12/13 | DB2 Server v11.1 | | Docker image with driver provided | :white_check_mark: | :white_check_mark: (Tag: "-mysql") | :white_check_mark: | :white_check_mark: | | -| JDBC driver | [H2 1.4.200](https://github.com/h2database/h2database) | [MariaDB Connector/J 2.6.2](https://github.com/MariaDB/mariadb-connector-j) | [MSSQL-JDBC 7.4.1.jre8](https://github.com/Microsoft/mssql-jdbc) | [PostgreSQL JDBC Driver 42.2.14](https://github.com/pgjdbc/pgjdbc) | | +| JDBC driver | [H2 2.1.214](https://github.com/h2database/h2database) | [MariaDB Connector/J 2.7.8](https://github.com/MariaDB/mariadb-connector-j) | [MSSQL-JDBC 10.2.3.jre8](https://github.com/Microsoft/mssql-jdbc) | [PostgreSQL JDBC Driver 42.3.8](https://github.com/pgjdbc/pgjdbc) | | | Status | Test, Dev | Production grade | Production grade | Test, Dev | Test, Dev | ## (Optional) RabbitMQ: 3.6,3.7,3.8 diff --git a/docs/content/guides/runhawkbit.md b/docs/content/guides/runhawkbit.md index 4737d2a3d..d45096df6 100644 --- a/docs/content/guides/runhawkbit.md +++ b/docs/content/guides/runhawkbit.md @@ -48,7 +48,7 @@ For this you can either edit the existing _application.properties_ or create a [ ```properties spring.jpa.database=MYSQL -spring.datasource.url=jdbc:mysql://localhost:3306/YOUR_SCHEMA +spring.datasource.url=jdbc:mariadb://localhost:3306/YOUR_SCHEMA spring.datasource.username=YOUR_USER spring.datasource.password=YOUR_PWD spring.datasource.driverClassName=org.mariadb.jdbc.Driver diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java index 7ded8ba85..39370b937 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java @@ -19,10 +19,11 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.bus.BusProperties; import org.springframework.cloud.bus.ConditionalOnBusEnabled; import org.springframework.cloud.bus.ServiceMatcher; import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan; -import org.springframework.cloud.stream.annotation.StreamMessageConverter; import org.springframework.context.ApplicationEvent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,6 +44,7 @@ import io.protostuff.Schema; @Configuration @RemoteApplicationEventScan(basePackages = "org.eclipse.hawkbit.repository.event.remote") @PropertySource("classpath:/hawkbit-eventbus-defaults.properties") +@EnableConfigurationProperties(BusProperties.class) public class EventPublisherAutoConfiguration { /** * Server internal event publisher that allows parallel event processing if @@ -138,7 +140,6 @@ public class EventPublisherAutoConfiguration { * @return the protostuff io message converter */ @Bean - @StreamMessageConverter public MessageConverter busProtoBufConverter() { return new BusProtoStuffMessageConverter(); } diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index c9b010721..702289d2f 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -58,6 +58,7 @@ import org.springframework.boot.web.servlet.ServletListenerRegistrationBean; import org.springframework.context.annotation.AdviceMode; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Lazy; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.PropertySource; import org.springframework.core.Ordered; @@ -477,6 +478,7 @@ public class SecurityManagedConfiguration { public static class RestSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { @Autowired + @Lazy private UserAuthenticationFilter userAuthenticationFilter; @Autowired(required = false) diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java index e71011268..bf7711268 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java @@ -35,10 +35,10 @@ import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest; import org.eclipse.hawkbit.dmf.json.model.DmfMetadata; import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule; import org.eclipse.hawkbit.repository.SystemManagement; +import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; -import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Artifact; @@ -136,7 +136,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { final Action action = createAction(createDistributionSet); final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent( - action, serviceMatcher.getServiceId()); + action, serviceMatcher.getBusId()); amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = getCaptureAddressEvent(targetAssignDistributionSetEvent); final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage, @@ -183,7 +183,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { Mockito.when(rabbitTemplate.convertSendAndReceive(any())).thenReturn(receivedList); final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent( - action, serviceMatcher.getServiceId()); + action, serviceMatcher.getBusId()); amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); final Message sendMessage = getCaptureAddressEvent(targetAssignDistributionSetEvent); final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage, @@ -220,7 +220,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { void sendUpdateAttributesRequest() { final String amqpUri = "amqp://anyhost"; final TargetAttributesRequestedEvent targetAttributesRequestedEvent = new TargetAttributesRequestedEvent(TENANT, - 1L, CONTROLLER_ID, amqpUri, Target.class, serviceMatcher.getServiceId()); + 1L, CONTROLLER_ID, amqpUri, Target.class, serviceMatcher.getBusId()); amqpMessageDispatcherService.targetTriggerUpdateAttributes(targetAttributesRequestedEvent); @@ -235,7 +235,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { when(action.getId()).thenReturn(1L); when(action.getTarget()).thenReturn(testTarget); final CancelTargetAssignmentEvent cancelTargetAssignmentDistributionSetEvent = new CancelTargetAssignmentEvent( - action, serviceMatcher.getServiceId()); + action, serviceMatcher.getBusId()); amqpMessageDispatcherService .targetCancelAssignmentToDistributionSet(cancelTargetAssignmentDistributionSetEvent); final Message sendMessage = createArgumentCapture(AMQP_URI); @@ -250,7 +250,7 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { // setup final String amqpUri = "amqp://anyhost"; final TargetDeletedEvent targetDeletedEvent = new TargetDeletedEvent(TENANT, 1L, CONTROLLER_ID, amqpUri, - Target.class, serviceMatcher.getServiceId()); + Target.class, serviceMatcher.getBusId()); // test amqpMessageDispatcherService.targetDelete(targetDeletedEvent); @@ -267,13 +267,13 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { // setup final String noAmqpUri = "http://anyhost"; final TargetDeletedEvent targetDeletedEvent = new TargetDeletedEvent(TENANT, 1L, CONTROLLER_ID, noAmqpUri, - Target.class, serviceMatcher.getServiceId()); + Target.class, serviceMatcher.getBusId()); // test amqpMessageDispatcherService.targetDelete(targetDeletedEvent); // verify - Mockito.verifyZeroInteractions(senderService); + Mockito.verifyNoInteractions(senderService); } @Test @@ -283,13 +283,13 @@ class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { // setup final String noAmqpUri = null; final TargetDeletedEvent targetDeletedEvent = new TargetDeletedEvent(TENANT, 1L, CONTROLLER_ID, noAmqpUri, - Target.class, serviceMatcher.getServiceId()); + Target.class, serviceMatcher.getBusId()); // test amqpMessageDispatcherService.targetDelete(targetDeletedEvent); // verify - Mockito.verifyZeroInteractions(senderService); + Mockito.verifyNoInteractions(senderService); } private void assertCancelMessage(final Message sendMessage) { diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java index a4d4630a2..46f711357 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java @@ -40,6 +40,7 @@ import org.eclipse.hawkbit.dmf.json.model.DmfMultiActionRequest.DmfMultiActionEl import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule; import org.eclipse.hawkbit.dmf.json.model.DmfTarget; import org.eclipse.hawkbit.repository.DeploymentManagement; +import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; @@ -48,7 +49,6 @@ import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent; -import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; import org.eclipse.hawkbit.repository.event.remote.entity.DistributionSetCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.RolloutGroupCreatedEvent; @@ -543,7 +543,7 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer final DistributionSet distributionSet = createTargetAndDistributionSetAndAssign(controllerId, DOWNLOAD_ONLY); final Message message = assertReplyMessageHeader(EventTopic.DOWNLOAD, controllerId); - Mockito.verifyZeroInteractions(getDeadletterListener()); + Mockito.verifyNoInteractions(getDeadletterListener()); assertThat(message).isNotNull(); final Map headers = message.getMessageProperties().getHeaders(); @@ -680,14 +680,14 @@ public class AmqpMessageDispatcherServiceIntegrationTest extends AbstractAmqpSer final List controllerIds) { assertSoftwareModules(softwareModules, request.getSoftwareModules()); - List tokens = controllerIds.stream().map(controllerId -> { + final List tokens = controllerIds.stream().map(controllerId -> { final Optional target = controllerManagement.getByControllerId(controllerId); assertThat(target).isPresent(); return target.get().getSecurityToken(); }).collect(Collectors.toList()); - List requestTargets = request.getTargets(); + final List requestTargets = request.getTargets(); assertThat(requestTargets).hasSameSizeAs(controllerIds); requestTargets.forEach(requestTarget -> { diff --git a/hawkbit-dmf/hawkbit-dmf-rabbitmq-test/pom.xml b/hawkbit-dmf/hawkbit-dmf-rabbitmq-test/pom.xml index ed11d6f3e..79d3006c2 100644 --- a/hawkbit-dmf/hawkbit-dmf-rabbitmq-test/pom.xml +++ b/hawkbit-dmf/hawkbit-dmf-rabbitmq-test/pom.xml @@ -57,8 +57,8 @@ compile - org.springframework - spring-web + org.springframework.boot + spring-boot-starter-web compile diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEvent.java index 968a0aba7..739f56c73 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEvent.java @@ -11,6 +11,8 @@ package org.eclipse.hawkbit.repository.event.remote; import org.eclipse.hawkbit.repository.event.TenantAwareEvent; import org.springframework.cloud.bus.event.RemoteApplicationEvent; +import com.cronutils.utils.StringUtils; + /** * A distributed tenant aware event. It's the base class of the other * distributed events. All the necessary information of distributing events to @@ -40,7 +42,8 @@ public class RemoteTenantAwareEvent extends RemoteApplicationEvent implements Te * the applicationId */ public RemoteTenantAwareEvent(final Object source, final String tenant, final String applicationId) { - super(source, applicationId); + // due to a bug in Spring Cloud, we cannot pass null for applicationId + super(source, applicationId != null ? applicationId : StringUtils.EMPTY); this.tenant = tenant; } diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/model/helper/EventPublisherHolder.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/model/helper/EventPublisherHolder.java index 1ff3fc040..1b2e71f57 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/model/helper/EventPublisherHolder.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/model/helper/EventPublisherHolder.java @@ -53,6 +53,13 @@ public final class EventPublisherHolder { * when available or {@link BusProperties} otherwise. */ public String getApplicationId() { - return serviceMatcher != null ? serviceMatcher.getServiceId() : bus.getId(); + String id = null; + if (serviceMatcher != null) { + id = serviceMatcher.getBusId(); + } + if (id == null) { + id = bus.getId(); + } + return id; } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/pom.xml b/hawkbit-repository/hawkbit-repository-jpa/pom.xml index dcae80efd..5bc7a37cf 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/pom.xml +++ b/hawkbit-repository/hawkbit-repository-jpa/pom.xml @@ -40,6 +40,10 @@ hawkbit-artifact-repository-filesystem ${project.version} + + org.springframework + spring-core + org.springframework.boot spring-boot-starter-data-jpa @@ -56,6 +60,10 @@ org.flywaydb flyway-core + + org.flywaydb + flyway-mysql + cz.jirutka.rsql rsql-parser @@ -72,6 +80,10 @@ javax.xml.bind jaxb-api + + org.hibernate.validator + hibernate-validator + diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java index 7996aa020..0f88eec1a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/ActionRepository.java @@ -50,7 +50,7 @@ public interface ActionRepository extends BaseEntityRepository, * @return the found {@link Action} */ @EntityGraph(value = "Action.all", type = EntityGraphType.LOAD) - Optional getById(Long actionId); + Optional getActionById(Long actionId); /** * Retrieves all {@link Action}s which are referring the given diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java index 650bb3a3e..96c86a8ad 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java @@ -233,11 +233,11 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont * Constructor. * * @param defaultEventInterval - * default timer value to use for interval between events. This puts - * an upper bound for the timer value + * default timer value to use for interval between events. + * This puts an upper bound for the timer value * @param minimumEventInterval - * for loading {@link DistributionSet#getModules()}. This puts a - * lower bound to the timer value + * for loading {@link DistributionSet#getModules()}. This + * puts a lower bound to the timer value * @param timeUnit * representing the unit of time to be used for timer. */ @@ -252,15 +252,16 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont } /** - * This method calculates the time interval until the next event based on the - * desired number of events before the time when interval is reset to default. - * The return value is bounded by {@link EventTimer#defaultEventInterval} and + * This method calculates the time interval until the next event based + * on the desired number of events before the time when interval is + * reset to default. The return value is bounded by + * {@link EventTimer#defaultEventInterval} and * {@link EventTimer#minimumEventInterval}. * * @param eventCount - * number of events desired until the interval is reset to default. - * This is not guaranteed as the interval between events cannot be - * less than the minimum interval + * number of events desired until the interval is reset to + * default. This is not guaranteed as the interval between + * events cannot be less than the minimum interval * @param timerResetTime * time when exponential forwarding should reset to default * @@ -345,8 +346,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont } @Override - public List findActiveActionsWithHighestWeight(final String controllerId, - final int maxActionCount) { + public List findActiveActionsWithHighestWeight(final String controllerId, final int maxActionCount) { return findActiveActionsWithHighestWeightConsideringDefault(controllerId, maxActionCount); } @@ -357,7 +357,7 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont @Override public Optional findActionWithDetails(final long actionId) { - return actionRepository.getById(actionId); + return actionRepository.getActionById(actionId); } @Override @@ -394,8 +394,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont private Target createTarget(final String controllerId, final URI address, final String name) { final Target result = targetRepository.save((JpaTarget) entityFactory.target().create() - .controllerId(controllerId).description("Plug and Play target: " + controllerId).name((StringUtils.hasText(name) ? name : controllerId)) - .status(TargetUpdateStatus.REGISTERED).lastTargetQuery(System.currentTimeMillis()) + .controllerId(controllerId).description("Plug and Play target: " + controllerId) + .name((StringUtils.hasText(name) ? name : controllerId)).status(TargetUpdateStatus.REGISTERED) + .lastTargetQuery(System.currentTimeMillis()) .address(Optional.ofNullable(address).map(URI::toString).orElse(null)).build()); afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher() @@ -457,8 +458,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont /** * Sets {@link Target#getLastTargetQuery()} by native SQL in order to avoid - * raising opt lock revision as this update is not mission critical and in fact - * only written by {@link ControllerManagement}, i.e. the target itself. + * raising opt lock revision as this update is not mission critical and in + * fact only written by {@link ControllerManagement}, i.e. the target + * itself. */ private void setLastTargetQuery(final String tenant, final long currentTimeMillis, final List chunk) { final Map paramMapping = Maps.newHashMapWithExpectedSize(chunk.size()); @@ -486,8 +488,9 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont } /** - * Stores target directly to DB in case either {@link Target#getAddress()} or - * {@link Target#getUpdateStatus()} or {@link Target#getName()} changes or the buffer queue is full. + * Stores target directly to DB in case either {@link Target#getAddress()} + * or {@link Target#getUpdateStatus()} or {@link Target#getName()} changes + * or the buffer queue is full. * */ private Target updateTarget(final JpaTarget toUpdate, final URI address, final String name) { @@ -601,12 +604,13 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont /** * Handles the case where the {@link Action.Status#DOWNLOADED} status is - * reported by the device. In case the update is finished, a controllerId will - * be returned to trigger a request for attributes. + * reported by the device. In case the update is finished, a controllerId + * will be returned to trigger a request for attributes. * * @param action * updated action - * @return a present controllerId in case the attributes needs to be requested. + * @return a present controllerId in case the attributes needs to be + * requested. */ private Optional handleDownloadedActionStatus(final JpaAction action) { if (!isDownloadOnly(action)) { @@ -644,12 +648,13 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont /** * Handles the case where the {@link Action.Status#FINISHED} status is - * reported by the device. In case the update is finished, a controllerId will - * be returned to trigger a request for attributes. + * reported by the device. In case the update is finished, a controllerId + * will be returned to trigger a request for attributes. * * @param action * updated action - * @return a present controllerId in case the attributes needs to be requested. + * @return a present controllerId in case the attributes needs to be + * requested. */ private Optional handleFinishedAndStoreInTargetStatus(final JpaAction action) { final JpaTarget target = (JpaTarget) action.getTarget(); @@ -689,8 +694,8 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont final UpdateMode mode) { /* - * Constraints on attribute keys & values are not validated by EclipseLink. - * Hence, they are validated here. + * Constraints on attribute keys & values are not validated by + * EclipseLink. Hence, they are validated here. */ if (data.entrySet().stream().anyMatch(e -> !isAttributeEntryValid(e))) { throw new InvalidTargetAttributeException(); @@ -767,8 +772,8 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont } /** - * Registers retrieved status for given {@link Target} and {@link Action} if it - * does not exist yet. + * Registers retrieved status for given {@link Target} and {@link Action} if + * it does not exist yet. * * @param actionId * to the handle status for @@ -1034,8 +1039,8 @@ public class JpaControllerManagement extends JpaActionManagement implements Cont } private void cancelAssignDistributionSetEvent(final Action action) { - afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher().publishEvent( - new CancelTargetAssignmentEvent(action, eventPublisherHolder.getApplicationId()))); + afterCommit.afterCommit(() -> eventPublisherHolder.getEventPublisher() + .publishEvent(new CancelTargetAssignmentEvent(action, eventPublisherHolder.getApplicationId()))); } // for testing diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index 0c13cf848..509867c8d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -391,8 +391,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets); setAssignedDistributionSetAndTargetUpdateStatus(assignmentStrategy, distributionSetEntity, targetEntitiesIdsChunks); - final Map assignedActions = createActions(initiatedBy, targetsWithActionType, targetEntities, - assignmentStrategy, distributionSetEntity); + final Map assignedActions = createActions(initiatedBy, targetsWithActionType, + targetEntities, assignmentStrategy, distributionSetEntity); // create initial action status when action is created so we remember // the initial running status because we will change the status // of the action itself and with this action status we have a nicer @@ -510,7 +510,8 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl final boolean isConfirmationRequired) { if (actionStatus.getStatus() == Status.WAIT_FOR_CONFIRMATION) { if (action.getStatus().equals(Status.RUNNING)) { - // action is in RUNNING state only if it's confirmed during assignment already + // action is in RUNNING state only if it's confirmed during + // assignment already if (!isConfirmationRequired) { // confirmation given on assignment dialog actionStatus.addMessage( @@ -689,9 +690,9 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl return Collections.unmodifiableList(savedActions); } - private void closeOrCancelOpenDeviceActions(final List actions){ + private void closeOrCancelOpenDeviceActions(final List actions) { final List targetIds = actions.stream().map(JpaAction::getTarget).map(Target::getId) - .collect(Collectors.toList()); + .collect(Collectors.toList()); if (isActionsAutocloseEnabled()) { onlineDsAssignmentStrategy.closeObsoleteUpdateActions(targetIds); } else { @@ -741,7 +742,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl @Override public Optional findActionWithDetails(final long actionId) { - return actionRepository.getById(actionId); + return actionRepository.getActionById(actionId); } @Override @@ -783,6 +784,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl public List findActiveActionsWithHighestWeight(final String controllerId, final int maxActionCount) { return findActiveActionsWithHighestWeightConsideringDefault(controllerId, maxActionCount); } + @Override public int getWeightConsideringDefault(final Action action) { return super.getWeightConsideringDefault(action); @@ -1006,7 +1008,7 @@ public class JpaDeploymentManagement extends JpaActionManagement implements Depl private boolean isConfirmationFlowEnabled() { return TenantConfigHelper.usingContext(systemSecurityContext, tenantConfigurationManagement) - .isConfirmationFlowEnabled(); + .isConfirmationFlowEnabled(); } private T getConfigValue(final String key, final Class valueType) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java index 96d96f4c3..82e730e97 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java @@ -109,7 +109,7 @@ import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.persistence.config.PersistenceUnitProperties; -import org.hibernate.validator.HibernateValidatorConfiguration; +import org.hibernate.validator.BaseHibernateValidatorConfiguration; import org.springframework.beans.factory.ObjectProvider; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; @@ -390,7 +390,7 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { public MethodValidationPostProcessor methodValidationPostProcessor() { final MethodValidationPostProcessor processor = new MethodValidationPostProcessor(); processor.setValidator(Validation.byDefaultProvider().configure() - .addProperty(HibernateValidatorConfiguration.ALLOW_PARALLEL_METHODS_DEFINE_PARAMETER_CONSTRAINTS, + .addProperty(BaseHibernateValidatorConfiguration.ALLOW_PARALLEL_METHODS_DEFINE_PARAMETER_CONSTRAINTS, "true") .buildValidatorFactory().getValidator()); return processor; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_1__consolidate_artifact_sha1__H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_1__consolidate_artifact_sha1__H2.sql index 05b34fd5f..5611b8921 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_1__consolidate_artifact_sha1__H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_1__consolidate_artifact_sha1__H2.sql @@ -1,3 +1,4 @@ ALTER TABLE sp_artifact DROP COLUMN sha1_hash; -ALTER TABLE sp_artifact CHANGE gridfs_file_name sha1_hash varchar(40) not null; -CREATE INDEX sp_idx_artifact_02 ON sp_artifact (tenant, sha1_hash); \ No newline at end of file +ALTER TABLE sp_artifact ALTER COLUMN gridfs_file_name RENAME TO sha1_hash; +ALTER TABLE sp_artifact ALTER sha1_hash varchar(40) not null; +CREATE INDEX sp_idx_artifact_02 ON sp_artifact (tenant, sha1_hash); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_3__add_rollout_deleted_flag__H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_3__add_rollout_deleted_flag__H2.sql index d21679f3e..cdfafc74f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_3__add_rollout_deleted_flag__H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_10_3__add_rollout_deleted_flag__H2.sql @@ -2,14 +2,14 @@ ALTER TABLE sp_rollout ADD COLUMN deleted BOOLEAN; UPDATE sp_rollout SET deleted = 0; -ALTER TABLE sp_action MODIFY target BIGINT NOT NULL; -ALTER TABLE sp_action MODIFY distribution_set BIGINT NOT NULL; -ALTER TABLE sp_action MODIFY status INTEGER NOT NULL; -ALTER TABLE sp_action_status MODIFY status INTEGER NOT NULL; -ALTER TABLE sp_rollout MODIFY status INTEGER NOT NULL; -ALTER TABLE sp_rollout MODIFY distribution_set BIGINT NOT NULL; -ALTER TABLE sp_rolloutgroup MODIFY rollout BIGINT NOT NULL; -ALTER TABLE sp_rolloutgroup MODIFY status INTEGER NOT NULL; +ALTER TABLE sp_action ALTER target BIGINT NOT NULL; +ALTER TABLE sp_action ALTER distribution_set BIGINT NOT NULL; +ALTER TABLE sp_action ALTER status INTEGER NOT NULL; +ALTER TABLE sp_action_status ALTER status INTEGER NOT NULL; +ALTER TABLE sp_rollout ALTER status INTEGER NOT NULL; +ALTER TABLE sp_rollout ALTER distribution_set BIGINT NOT NULL; +ALTER TABLE sp_rolloutgroup ALTER rollout BIGINT NOT NULL; +ALTER TABLE sp_rolloutgroup ALTER status INTEGER NOT NULL; ALTER TABLE sp_ds_type_element DROP CONSTRAINT fk_ds_type_element_element; ALTER TABLE sp_ds_type_element diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_0__drop_target_info__H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_0__drop_target_info__H2.sql index a7f971373..beddebc02 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_0__drop_target_info__H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_0__drop_target_info__H2.sql @@ -26,6 +26,6 @@ ALTER TABLE sp_target REFERENCES sp_distribution_set (id); ALTER TABLE sp_target_info DROP CONSTRAINT fk_targ_stat_targ; -ALTER TABLE sp_target_info DROP INDEX sp_idx_target_info_02; +DROP INDEX sp_idx_target_info_02; -DROP TABLE sp_target_info; \ No newline at end of file +DROP TABLE sp_target_info; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_2__remove_unused_idexes___H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_2__remove_unused_idexes___H2.sql index 190250dfa..5e9dd339d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_2__remove_unused_idexes___H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_11_2__remove_unused_idexes___H2.sql @@ -1,8 +1,8 @@ -ALTER TABLE sp_action_status DROP INDEX sp_idx_action_status_01; -ALTER TABLE sp_rollout DROP INDEX sp_idx_rollout_01; -ALTER TABLE sp_rolloutgroup DROP INDEX sp_idx_rolloutgroup_01; -ALTER TABLE sp_target DROP INDEX sp_idx_target_02; -ALTER TABLE sp_target_filter_query DROP INDEX sp_idx_target_filter_query_01; -ALTER TABLE sp_distribution_set DROP INDEX sp_idx_distribution_set_01; -ALTER TABLE sp_distribution_set DROP INDEX sp_idx_distribution_set_02; +DROP INDEX sp_idx_action_status_01; +DROP INDEX sp_idx_rollout_01; +DROP INDEX sp_idx_rolloutgroup_01; +DROP INDEX sp_idx_target_02; +DROP INDEX sp_idx_target_filter_query_01; +DROP INDEX sp_idx_distribution_set_01; +DROP INDEX sp_idx_distribution_set_02; CREATE INDEX sp_idx_distribution_set_01 ON sp_distribution_set (tenant, deleted, complete); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_0__action_performance___H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_0__action_performance___H2.sql index 1dff4e13a..02b4199c9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_0__action_performance___H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_0__action_performance___H2.sql @@ -4,7 +4,7 @@ CASE WHEN (action_type = 'SOFT') THEN 1 WHEN (action_type = 'TIMEFORCED') THEN 2 ELSE 0 END; ALTER TABLE sp_action DROP COLUMN action_type; -ALTER TABLE sp_action CHANGE COLUMN action_type_new action_type integer; +ALTER TABLE sp_action ALTER COLUMN action_type_new RENAME TO action_type; ALTER TABLE sp_rollout ADD COLUMN action_type_new integer not null; UPDATE sp_rollout SET action_type_new = @@ -12,7 +12,7 @@ CASE WHEN (action_type = 'SOFT') THEN 1 WHEN (action_type = 'TIMEFORCED') THEN 2 ELSE 0 END; ALTER TABLE sp_rollout DROP COLUMN action_type; -ALTER TABLE sp_rollout CHANGE COLUMN action_type_new action_type integer; +ALTER TABLE sp_rollout ALTER COLUMN action_type_new RENAME to action_type; ALTER TABLE sp_target ADD COLUMN update_status_new integer not null; UPDATE sp_target SET update_status_new = @@ -22,4 +22,4 @@ CASE WHEN (update_status = 'IN_SYNC') THEN 1 WHEN (update_status = 'REGISTERED') THEN 4 ELSE 0 END; ALTER TABLE sp_target DROP COLUMN update_status; -ALTER TABLE sp_target CHANGE COLUMN update_status_new update_status integer; \ No newline at end of file +ALTER TABLE sp_target ALTER COLUMN update_status_new RENAME TO update_status; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_1__missing_non_null___H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_1__missing_non_null___H2.sql index deb2ab79d..91a3c26a4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_1__missing_non_null___H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_1__missing_non_null___H2.sql @@ -1,12 +1,12 @@ -ALTER TABLE sp_action_status_messages CHANGE COLUMN detail_message detail_message varchar(512) not null; -ALTER TABLE sp_action CHANGE COLUMN distribution_set distribution_set bigint not null; -ALTER TABLE sp_action CHANGE COLUMN target target bigint not null; -ALTER TABLE sp_action CHANGE COLUMN status status integer not null; -ALTER TABLE sp_action_status CHANGE COLUMN target_occurred_at target_occurred_at bigint not null; -ALTER TABLE sp_action_status CHANGE COLUMN status status integer not null; -ALTER TABLE sp_rollout CHANGE COLUMN distribution_set distribution_set bigint not null; -ALTER TABLE sp_rollout CHANGE COLUMN status status integer not null; -ALTER TABLE sp_rolloutgroup CHANGE COLUMN rollout rollout bigint not null; -ALTER TABLE sp_rolloutgroup CHANGE COLUMN status status integer not null; -ALTER TABLE sp_artifact CHANGE COLUMN sha1_hash sha1_hash varchar(40) not null; -ALTER TABLE sp_target CHANGE COLUMN controller_id controller_id varchar(64) not null; \ No newline at end of file +ALTER TABLE sp_action_status_messages ALTER detail_message varchar(512) not null; +ALTER TABLE sp_action ALTER distribution_set bigint not null; +ALTER TABLE sp_action ALTER target bigint not null; +ALTER TABLE sp_action ALTER status integer not null; +ALTER TABLE sp_action_status ALTER target_occurred_at bigint not null; +ALTER TABLE sp_action_status ALTER status integer not null; +ALTER TABLE sp_rollout ALTER distribution_set bigint not null; +ALTER TABLE sp_rollout ALTER status integer not null; +ALTER TABLE sp_rolloutgroup ALTER rollout bigint not null; +ALTER TABLE sp_rolloutgroup ALTER status integer not null; +ALTER TABLE sp_artifact ALTER sha1_hash varchar(40) not null; +ALTER TABLE sp_target ALTER controller_id varchar(64) not null; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_2__missing_non_null_enum___H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_2__missing_non_null_enum___H2.sql index 5a7755373..3c767e8c7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_2__missing_non_null_enum___H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_12_2__missing_non_null_enum___H2.sql @@ -1,3 +1,3 @@ -ALTER TABLE sp_target CHANGE COLUMN update_status update_status integer not null; -ALTER TABLE sp_rollout CHANGE COLUMN action_type action_type integer not null; -ALTER TABLE sp_action CHANGE COLUMN action_type action_type integer not null; \ No newline at end of file +ALTER TABLE sp_target ALTER update_status integer not null; +ALTER TABLE sp_rollout ALTER action_type integer not null; +ALTER TABLE sp_action ALTER action_type integer not null; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_7_1__reduce_length_enums___H2.sql b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_7_1__reduce_length_enums___H2.sql index ae9eef28e..dfa5a7d94 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_7_1__reduce_length_enums___H2.sql +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/db/migration/H2/V1_7_1__reduce_length_enums___H2.sql @@ -1,5 +1,5 @@ -ALTER TABLE sp_target_info MODIFY update_status VARCHAR(16) not null; -ALTER TABLE sp_action MODIFY action_type VARCHAR(16) not null; -ALTER TABLE sp_rollout MODIFY action_type VARCHAR(16) not null; -ALTER TABLE sp_tenant_configuration MODIFY conf_key VARCHAR(128) not null; -ALTER TABLE sp_tenant_configuration MODIFY conf_value VARCHAR(512) not null; \ No newline at end of file +ALTER TABLE sp_target_info ALTER update_status VARCHAR(16) not null; +ALTER TABLE sp_action ALTER action_type VARCHAR(16) not null; +ALTER TABLE sp_rollout ALTER action_type VARCHAR(16) not null; +ALTER TABLE sp_tenant_configuration ALTER conf_key VARCHAR(128) not null; +ALTER TABLE sp_tenant_configuration ALTER conf_value VARCHAR(512) not null; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/hawkbit-jpa-defaults.properties b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/hawkbit-jpa-defaults.properties index aebd7ee5d..6935451e5 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/hawkbit-jpa-defaults.properties +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/resources/hawkbit-jpa-defaults.properties @@ -12,7 +12,9 @@ spring.main.allow-bean-definition-overriding=true ### JPA / Datasource - START spring.jpa.database=H2 spring.jpa.show-sql=false -spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL; +# need to use legacy mode for now until we can upgrade EclipseLink +# (see details: https://github.com/eclipse-ee4j/eclipselink/issues/1393) +spring.datasource.url=jdbc:h2:mem:testdb;MODE=LEGACY; # Logging spring.datasource.eclipselink.logging.logger=JavaLogger spring.jpa.properties.eclipselink.logging.level=off diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java index a35dec6dd..976ca058d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java @@ -20,11 +20,11 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.ActionProperties; import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.junit.jupiter.api.Test; import io.qameta.allure.Description; import io.qameta.allure.Feature; import io.qameta.allure.Story; -import org.junit.jupiter.api.Test; @Feature("Component Tests - Repository") @Story("RemoteTenantAwareEvent Tests") @@ -109,7 +109,7 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest { final Action action = actionRepository.save(generateAction); final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent( - action.getTenant(), dsA.getId(), Arrays.asList(action), serviceMatcher.getServiceId(), + action.getTenant(), dsA.getId(), Arrays.asList(action), serviceMatcher.getBusId(), action.isMaintenanceWindowAvailable()); final TargetAssignDistributionSetEvent remoteEventProtoStuff = createProtoStuffEvent(assignmentEvent); @@ -135,7 +135,7 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest { final Action action = actionRepository.save(generateAction); final CancelTargetAssignmentEvent cancelEvent = new CancelTargetAssignmentEvent(action, - serviceMatcher.getServiceId()); + serviceMatcher.getBusId()); final CancelTargetAssignmentEvent remoteEventProtoStuff = createProtoStuffEvent(cancelEvent); assertCancelTargetAssignmentEvent(action, remoteEventProtoStuff); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java index 3c97a684e..f89fa7ea3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java @@ -1610,7 +1610,7 @@ class ControllerManagementTest extends AbstractJpaIntegrationTest { } private void assertLastActionStatusCodeInAction(final Long actionId, final Integer expectedLastActionStatusCode) { - final Optional action = actionRepository.getById(actionId); + final Optional action = actionRepository.getActionById(actionId); assertThat(action).isPresent(); assertThat(action.get().getLastActionStatusCode()).isEqualTo(Optional.ofNullable(expectedLastActionStatusCode)); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java index f9336c45c..f05bcaae3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java @@ -996,8 +996,8 @@ class DeploymentManagementTest extends AbstractJpaIntegrationTest { deploymentManagement.assignDistributionSets(Collections.singletonList(valideRequest1)).get(0)).getId(); final Long valideActionId2 = getFirstAssignedAction( deploymentManagement.assignDistributionSets(Collections.singletonList(valideRequest2)).get(0)).getId(); - assertThat(actionRepository.getById(valideActionId1).get().getWeight()).get().isEqualTo(Action.WEIGHT_MAX); - assertThat(actionRepository.getById(valideActionId2).get().getWeight()).get().isEqualTo(Action.WEIGHT_MIN); + assertThat(actionRepository.getActionById(valideActionId1).get().getWeight()).get().isEqualTo(Action.WEIGHT_MAX); + assertThat(actionRepository.getActionById(valideActionId2).get().getWeight()).get().isEqualTo(Action.WEIGHT_MIN); } /** diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/autocleanup/AutoActionCleanupTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/autocleanup/AutoActionCleanupTest.java index 60786f072..ed41a748b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/autocleanup/AutoActionCleanupTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/autocleanup/AutoActionCleanupTest.java @@ -117,7 +117,7 @@ public class AutoActionCleanupTest extends AbstractJpaIntegrationTest { autoActionCleanup.run(); assertThat(actionRepository.count()).isEqualTo(1); - assertThat(actionRepository.getById(action3)).isPresent(); + assertThat(actionRepository.getActionById(action3)).isPresent(); } @@ -149,8 +149,8 @@ public class AutoActionCleanupTest extends AbstractJpaIntegrationTest { autoActionCleanup.run(); assertThat(actionRepository.count()).isEqualTo(2); - assertThat(actionRepository.getById(action2)).isPresent(); - assertThat(actionRepository.getById(action3)).isPresent(); + assertThat(actionRepository.getActionById(action2)).isPresent(); + assertThat(actionRepository.getActionById(action3)).isPresent(); } @@ -189,7 +189,7 @@ public class AutoActionCleanupTest extends AbstractJpaIntegrationTest { autoActionCleanup.run(); assertThat(actionRepository.count()).isEqualTo(1); - assertThat(actionRepository.getById(action3)).isPresent(); + assertThat(actionRepository.getActionById(action3)).isPresent(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLSoftwareModuleFieldTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLSoftwareModuleFieldTest.java index 808c5ccd7..695350fbc 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLSoftwareModuleFieldTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/rsql/RSQLSoftwareModuleFieldTest.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.test.util.TestdataFactory; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; @@ -91,9 +92,6 @@ public class RSQLSoftwareModuleFieldTest extends AbstractJpaIntegrationTest { //wildcard entries assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*$*", 1); assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*§*", 1); - assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*Ö*", 1); - assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*Ä*", 1); - assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*Ü*", 1); assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*@*", 1); assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*/*", 1); assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*&*", 1); @@ -101,6 +99,15 @@ public class RSQLSoftwareModuleFieldTest extends AbstractJpaIntegrationTest { assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*\\**", 1); } + @Test + @Description("Test filter software module by name which contain mutated vowels ") + @Disabled("Temporarily disabled because test depends on collation settings of database") + public void testFilterByParameterNameWithUmlaut() { + assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*Ö*", 1); + assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*Ä*", 1); + assertRSQLQuery(SoftwareModuleFields.NAME.name() + "==*Ü*", 1); + } + @Test @Description("Test filter software module by description") public void testFilterByParameterDescription() { diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/MySqlTestDatabase.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/MySqlTestDatabase.java index 862f5553a..7d6c12745 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/MySqlTestDatabase.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/MySqlTestDatabase.java @@ -21,7 +21,7 @@ import org.slf4j.LoggerFactory; public class MySqlTestDatabase extends AbstractSqlTestDatabase { private static final Logger LOGGER = LoggerFactory.getLogger(MySqlTestDatabase.class); - protected static final String MYSQL_URI_PATTERN = "jdbc:mysql://{host}:{port}/{db}*"; + protected static final String MYSQL_URI_PATTERN = "jdbc:mariadb://{host}:{port}/{db}*"; public MySqlTestDatabase(final DatasourceContext context) { super(context); diff --git a/hawkbit-rest/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java b/hawkbit-rest/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java index 7419997c1..ab41fa1df 100644 --- a/hawkbit-rest/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java +++ b/hawkbit-rest/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/rest/api/DdiRootControllerRestApi.java @@ -35,13 +35,12 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST resource handling for root controller CRUD operations. */ -@RequestMapping(DdiRestConstants.BASE_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface DdiRootControllerRestApi { /** @@ -55,8 +54,9 @@ public interface DdiRootControllerRestApi { * of the software module * @return the response */ - @GetMapping(value = "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts", produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity> getSoftwareModulesArtifacts(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @PathVariable("softwareModuleId") final Long softwareModuleId); @@ -71,8 +71,8 @@ public interface DdiRootControllerRestApi { * * @return the response */ - @GetMapping(value = "/{controllerId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, - DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity getControllerBase(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId); @@ -93,7 +93,8 @@ public interface DdiRootControllerRestApi { * {@link HttpStatus#OK} or in case of partial download * {@link HttpStatus#PARTIAL_CONTENT}. */ - @GetMapping(value = "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}") + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}") ResponseEntity downloadArtifact(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @PathVariable("softwareModuleId") final Long softwareModuleId, @@ -114,7 +115,8 @@ public interface DdiRootControllerRestApi { * @return {@link ResponseEntity} with status {@link HttpStatus#OK} if * successful */ - @GetMapping(value = "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}" + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{fileName}" + DdiRestConstants.ARTIFACT_MD5_DWNL_SUFFIX, produces = MediaType.TEXT_PLAIN_VALUE) ResponseEntity downloadArtifactMd5(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @@ -129,36 +131,41 @@ public interface DdiRootControllerRestApi { * @param controllerId * of the target * @param actionId - * of the {@link DdiDeploymentBase} that matches to active actions. + * of the {@link DdiDeploymentBase} that matches to active + * actions. * @param resource - * an hashcode of the resource which indicates if the action has been - * changed, e.g. from 'soft' to 'force' and the eTag needs to be - * re-generated + * an hashcode of the resource which indicates if the action has + * been changed, e.g. from 'soft' to 'force' and the eTag needs + * to be re-generated * @param actionHistoryMessageCount * specifies the number of messages to be returned from action * history. Regardless of the passed value, in order to restrict - * resource utilization by controllers, maximum number of messages - * that are retrieved from database is limited by + * resource utilization by controllers, maximum number of + * messages that are retrieved from database is limited by * {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}. * - * actionHistoryMessageCount less than zero: retrieves the maximum - * allowed number of action status messages from history; + * actionHistoryMessageCount less than zero: retrieves the + * maximum allowed number of action status messages from history; * * actionHistoryMessageCount equal to zero: does not retrieve any * message; * * actionHistoryMessageCount greater than zero: retrieves the - * specified number of messages, limited by maximum allowed number. + * specified number of messages, limited by maximum allowed + * number. * * @return the response */ - @GetMapping(value = "/{controllerId}/" + DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}", produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity getControllerBasedeploymentAction(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("actionId") @NotEmpty final Long actionId, - @RequestParam(value = "c", required = false, defaultValue = "-1") final int resource, - @RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); + @RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "c", required = false, defaultValue = "-1") final int resource, + @RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); /** * This is the feedback channel for the {@link DdiDeploymentBase} action. @@ -174,9 +181,9 @@ public interface DdiRootControllerRestApi { * * @return the response */ - @PostMapping(value = "/{controllerId}/" + DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}/" - + DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, - DdiRestConstants.MEDIA_TYPE_CBOR }) + @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.DEPLOYMENT_BASE_ACTION + "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity postBasedeploymentActionFeedback(@Valid final DdiActionFeedback feedback, @PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @PathVariable("actionId") @NotEmpty final Long actionId); @@ -193,8 +200,9 @@ public interface DdiRootControllerRestApi { * * @return status of the request */ - @PutMapping(value = "/{controllerId}/" + DdiRestConstants.CONFIG_DATA_ACTION, consumes = { - MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @PutMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.CONFIG_DATA_ACTION, consumes = { MediaType.APPLICATION_JSON_VALUE, + DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity putConfigData(@Valid final DdiConfigData configData, @PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId); @@ -210,15 +218,16 @@ public interface DdiRootControllerRestApi { * * @return the {@link DdiCancel} response */ - @GetMapping(value = "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + "/{actionId}", produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + + "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, + DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity getControllerCancelAction(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("actionId") @NotEmpty final Long actionId); /** - * RequestMethod.POST method receiving the {@link DdiActionFeedback} from the - * target. + * RequestMethod.POST method receiving the {@link DdiActionFeedback} from + * the target. * * @param feedback * the {@link DdiActionFeedback} from the target. @@ -231,8 +240,8 @@ public interface DdiRootControllerRestApi { * * @return the {@link DdiActionFeedback} response */ - @PostMapping(value = "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + "/{actionId}/" - + DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, + @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + DdiRestConstants.CANCEL_ACTION + + "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity postCancelActionFeedback(@Valid final DdiActionFeedback feedback, @PathVariable("tenant") final String tenant, @@ -248,37 +257,42 @@ public interface DdiRootControllerRestApi { * @param controllerId * of the target * @param actionId - * of the {@link DdiDeploymentBase} that matches to installed action. + * of the {@link DdiDeploymentBase} that matches to installed + * action. * @param actionHistoryMessageCount * specifies the number of messages to be returned from action * history. Regardless of the passed value, in order to restrict - * resource utilization by controllers, maximum number of messages - * that are retrieved from database is limited by + * resource utilization by controllers, maximum number of + * messages that are retrieved from database is limited by * {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}. * - * actionHistoryMessageCount less than zero: retrieves the maximum - * allowed number of action status messages from history; + * actionHistoryMessageCount less than zero: retrieves the + * maximum allowed number of action status messages from history; * * actionHistoryMessageCount equal to zero: does not retrieve any * message; * * actionHistoryMessageCount greater than zero: retrieves the - * specified number of messages, limited by maximum allowed number. + * specified number of messages, limited by maximum allowed + * number. * - * @return the {@link DdiDeploymentBase}. The response is of same format as for - * the /deploymentBase resource. + * @return the {@link DdiDeploymentBase}. The response is of same format as + * for the /deploymentBase resource. */ - @GetMapping(value = "/{controllerId}/" + DdiRestConstants.INSTALLED_BASE_ACTION + "/{actionId}", produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.INSTALLED_BASE_ACTION + "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity getControllerInstalledAction(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("actionId") @NotEmpty final Long actionId, - @RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); + @RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); /** - * Returns the confirmation base with the current auto-confirmation state for a - * given controllerId and toggle links. In case there are actions present where - * the confirmation is required, a reference to it will be returned as well. + * Returns the confirmation base with the current auto-confirmation state + * for a given controllerId and toggle links. In case there are actions + * present where the confirmation is required, a reference to it will be + * returned as well. * * @param tenant * the controllerId is corresponding too @@ -286,8 +300,9 @@ public interface DdiRootControllerRestApi { * to check the state for * @return the state as {@link DdiAutoConfirmationState} */ - @GetMapping(value = "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.CONFIRMATION_BASE, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity getConfirmationBase(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId); @@ -299,37 +314,41 @@ public interface DdiRootControllerRestApi { * @param controllerId * of the target * @param actionId - * of the {@link DdiConfirmationBaseAction} that matches to active - * actions in WAITING_FOR_CONFIRMATION status. + * of the {@link DdiConfirmationBaseAction} that matches to + * active actions in WAITING_FOR_CONFIRMATION status. * @param resource - * an hashcode of the resource which indicates if the action has been - * changed, e.g. from 'soft' to 'force' and the eTag needs to be - * re-generated + * an hashcode of the resource which indicates if the action has + * been changed, e.g. from 'soft' to 'force' and the eTag needs + * to be re-generated * @param actionHistoryMessageCount * specifies the number of messages to be returned from action * history. Regardless of the passed value, in order to restrict - * resource utilization by controllers, maximum number of messages - * that are retrieved from database is limited by + * resource utilization by controllers, maximum number of + * messages that are retrieved from database is limited by * {@link RepositoryConstants#MAX_ACTION_HISTORY_MSG_COUNT}. * - * actionHistoryMessageCount less than zero: retrieves the maximum - * allowed number of action status messages from history; + * actionHistoryMessageCount less than zero: retrieves the + * maximum allowed number of action status messages from history; * * actionHistoryMessageCount equal to zero: does not retrieve any * message; * * actionHistoryMessageCount greater than zero: retrieves the - * specified number of messages, limited by maximum allowed number. + * specified number of messages, limited by maximum allowed + * number. * * @return the response */ - @GetMapping(value = "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/{actionId}", produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) + @GetMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.CONFIRMATION_BASE + "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity getConfirmationBaseAction(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId, @PathVariable("actionId") @NotEmpty final Long actionId, - @RequestParam(value = "c", required = false, defaultValue = "-1") final int resource, - @RequestParam(value = "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); + @RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "c", required = false, defaultValue = "-1") final int resource, + @RequestParam(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + + "actionHistory", defaultValue = DdiRestConstants.NO_ACTION_HISTORY) final Integer actionHistoryMessageCount); /** * This is the feedback channel for the {@link DdiConfirmationBaseAction} @@ -346,16 +365,16 @@ public interface DdiRootControllerRestApi { * * @return the response */ - @PostMapping(value = "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/{actionId}/" - + DdiRestConstants.FEEDBACK, consumes = { MediaType.APPLICATION_JSON_VALUE, - DdiRestConstants.MEDIA_TYPE_CBOR }) + @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.CONFIRMATION_BASE + "/{actionId}/" + DdiRestConstants.FEEDBACK, consumes = { + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity postConfirmationActionFeedback(@Valid final DdiConfirmationFeedback feedback, @PathVariable("tenant") final String tenant, @PathVariable("controllerId") final String controllerId, @PathVariable("actionId") @NotEmpty final Long actionId); /** - * Activate auto confirmation for a given controllerId. Will use the provided - * initiator and remark field from the provided + * Activate auto confirmation for a given controllerId. Will use the + * provided initiator and remark field from the provided * {@link DdiActivateAutoConfirmation}. If not present, the values will be * prefilled with a default remark and the CONTROLLER as initiator. * @@ -369,9 +388,9 @@ public interface DdiRootControllerRestApi { * {@link org.springframework.http.HttpStatus#CONFLICT} in case * auto-confirmation was active already. */ - @PostMapping(value = "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/" - + DdiRestConstants.AUTO_CONFIRM_ACTIVATE, consumes = { MediaType.APPLICATION_JSON_VALUE, - DdiRestConstants.MEDIA_TYPE_CBOR }) + @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.CONFIRMATION_BASE + "/" + DdiRestConstants.AUTO_CONFIRM_ACTIVATE, consumes = { + MediaType.APPLICATION_JSON_VALUE, DdiRestConstants.MEDIA_TYPE_CBOR }) ResponseEntity activateAutoConfirmation(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId, @Valid @RequestBody(required = false) final DdiActivateAutoConfirmation body); @@ -386,8 +405,8 @@ public interface DdiRootControllerRestApi { * @return {@link org.springframework.http.HttpStatus#OK} if successfully * executed */ - @PostMapping(value = "/{controllerId}/" + DdiRestConstants.CONFIRMATION_BASE + "/" - + DdiRestConstants.AUTO_CONFIRM_DEACTIVATE) + @PostMapping(value = DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/" + + DdiRestConstants.CONFIRMATION_BASE + "/" + DdiRestConstants.AUTO_CONFIRM_DEACTIVATE) ResponseEntity deactivateAutoConfirmation(@PathVariable("tenant") final String tenant, @PathVariable("controllerId") @NotEmpty final String controllerId); } diff --git a/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java b/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java index 7337362f5..efa41e0eb 100644 --- a/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java +++ b/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DataConversionHelper.java @@ -104,7 +104,7 @@ public final class DataConversionHelper { new SoftwareData(artifact.getSoftwareModule().getId(), artifact.getFilename(), artifact.getId(), artifact.getSha1Hash())), ApiType.DDI, request.getURI()) - .forEach(entry -> file.add(new Link(entry.getRef()).withRel(entry.getRel()))); + .forEach(entry -> file.add(Link.of(entry.getRef()).withRel(entry.getRel()).expand())); return file; @@ -118,19 +118,19 @@ public final class DataConversionHelper { confirmationBase.add(WebMvcLinkBuilder .linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .deactivateAutoConfirmation(tenantAware.getCurrentTenant(), controllerId)) - .withRel(DdiRestConstants.AUTO_CONFIRM_DEACTIVATE)); + .withRel(DdiRestConstants.AUTO_CONFIRM_DEACTIVATE).expand()); } else { confirmationBase.add(WebMvcLinkBuilder .linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .activateAutoConfirmation(tenantAware.getCurrentTenant(), controllerId, null)) - .withRel(DdiRestConstants.AUTO_CONFIRM_ACTIVATE)); + .withRel(DdiRestConstants.AUTO_CONFIRM_ACTIVATE).expand()); } if (activeAction != null && activeAction.isWaitingConfirmation()) { confirmationBase.add(WebMvcLinkBuilder .linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .getConfirmationBaseAction(tenantAware.getCurrentTenant(), controllerId, activeAction.getId(), calculateEtag(activeAction), null)) - .withRel(DdiRestConstants.CONFIRMATION_BASE)); + .withRel(DdiRestConstants.CONFIRMATION_BASE).expand()); } return confirmationBase; @@ -147,14 +147,14 @@ public final class DataConversionHelper { .methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .getConfirmationBaseAction(tenantAware.getCurrentTenant(), target.getControllerId(), activeAction.getId(), calculateEtag(activeAction), null)) - .withRel(DdiRestConstants.CONFIRMATION_BASE)); + .withRel(DdiRestConstants.CONFIRMATION_BASE).expand()); } else if (activeAction.isCancelingOrCanceled()) { result.add(WebMvcLinkBuilder .linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .getControllerCancelAction(tenantAware.getCurrentTenant(), target.getControllerId(), activeAction.getId())) - .withRel(DdiRestConstants.CANCEL_ACTION)); + .withRel(DdiRestConstants.CANCEL_ACTION).expand()); } else { // we need to add the hashcode here of the actionWithStatus // because the action might @@ -165,7 +165,7 @@ public final class DataConversionHelper { .methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .getControllerBasedeploymentAction(tenantAware.getCurrentTenant(), target.getControllerId(), activeAction.getId(), calculateEtag(activeAction), null)) - .withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION)); + .withRel(DdiRestConstants.DEPLOYMENT_BASE_ACTION).expand()); } } @@ -175,14 +175,14 @@ public final class DataConversionHelper { .linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .getControllerInstalledAction(tenantAware.getCurrentTenant(), target.getControllerId(), installedAction.getId(), null)) - .withRel(DdiRestConstants.INSTALLED_BASE_ACTION)); + .withRel(DdiRestConstants.INSTALLED_BASE_ACTION).expand()); } if (target.isRequestControllerAttributes()) { result.add(WebMvcLinkBuilder .linkTo(WebMvcLinkBuilder.methodOn(DdiRootController.class, tenantAware.getCurrentTenant()) .putConfigData(null, tenantAware.getCurrentTenant(), target.getControllerId())) - .withRel(DdiRestConstants.CONFIG_DATA_ACTION)); + .withRel(DdiRestConstants.CONFIG_DATA_ACTION).expand()); } return result; diff --git a/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java b/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java index 30bdd8d38..08868c88c 100644 --- a/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java +++ b/hawkbit-rest/hawkbit-ddi-resource/src/main/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootController.java @@ -82,6 +82,7 @@ import org.springframework.http.server.ServletServerHttpRequest; import org.springframework.util.CollectionUtils; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.context.WebApplicationContext; @@ -210,7 +211,7 @@ public class DdiRootController implements DdiRootControllerRestApi { (length, shippedSinceLastEvent, total) -> eventPublisher.publishEvent(new DownloadProgressEvent( tenantAware.getCurrentTenant(), statusId, shippedSinceLastEvent, - serviceMatcher != null ? serviceMatcher.getServiceId() : bus.getId()))); + serviceMatcher != null ? serviceMatcher.getBusId() : bus.getId()))); } } diff --git a/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java b/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java index 7db95d69c..a8c9a52dd 100644 --- a/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java +++ b/hawkbit-rest/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java @@ -738,9 +738,9 @@ public class DdiDeploymentBaseTest extends AbstractDDiApiIntegrationTest { } private static class ActionStatusCondition extends Condition { - private final Status status; + private final Action.Status status; - public ActionStatusCondition(final Status status) { + public ActionStatusCondition(final Action.Status status) { this.status = status; } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtActionId.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtActionId.java index 91f259e21..40bbf94b3 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtActionId.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/distributionset/MgmtActionId.java @@ -21,7 +21,8 @@ import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; /** - * Representation of an Action Id as a Json Object with link to the Action resource + * Representation of an Action Id as a Json Object with link to the Action + * resource */ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) @@ -34,14 +35,15 @@ public class MgmtActionId extends RepresentationModel { /** * Constructor + * * @param actionId - * the actionId + * the actionId * @param controllerId - * the controller Id + * the controller Id */ public MgmtActionId(final String controllerId, final long actionId) { this.actionId = actionId; - add(linkTo(methodOn(MgmtTargetRestApi.class).getAction(controllerId, actionId)).withSelfRel()); + add(linkTo(methodOn(MgmtTargetRestApi.class).getAction(controllerId, actionId)).withSelfRel().expand()); } @JsonProperty("id") diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtActionRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtActionRestApi.java index c8edc7636..9d2a1a75f 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtActionRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtActionRestApi.java @@ -15,13 +15,12 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST API providing (read-only) access to actions. */ -@RequestMapping(MgmtRestConstants.ACTION_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtActionRestApi { /** @@ -47,7 +46,8 @@ public interface MgmtActionRestApi { * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.ACTION_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getActions( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -56,13 +56,16 @@ public interface MgmtActionRestApi { @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_REPRESENTATION_MODE_DEFAULT) String representationModeParam); /** - * Handles the GET request of retrieving a specific Action by actionId + * Handles the GET request of retrieving a specific {@link MgmtAction} by + * its actionId. * * @param actionId + * The ID of the requested action * - * @return the action + * @return the {@link MgmtAction} */ - @GetMapping(value = "/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) - ResponseEntity getAction( - @PathVariable("actionId") Long actionId); + @GetMapping(value = MgmtRestConstants.ACTION_V1_REQUEST_MAPPING + "/{actionId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + ResponseEntity getAction(@PathVariable("actionId") Long actionId); + } \ No newline at end of file diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtBasicAuthRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtBasicAuthRestApi.java index c83065bc0..a9f921f36 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtBasicAuthRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtBasicAuthRestApi.java @@ -13,19 +13,19 @@ import org.springframework.hateoas.MediaTypes; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; /** * Api for handling basic auth user validation */ -@RequestMapping(MgmtRestConstants.AUTH_V1_REQUEST_MAPPING) @SuppressWarnings("squid:S1609") +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtBasicAuthRestApi { /** * Handles the GET request of basic auth. * * @return the userinfo with status OK. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.AUTH_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity validateBasicAuth(); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetRestApi.java index 89fd7d1e7..92b479f61 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetRestApi.java @@ -33,13 +33,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling for DistributionSet CRUD operations. */ -@RequestMapping(MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtDistributionSetRestApi { /** @@ -61,7 +60,8 @@ public interface MgmtDistributionSetRestApi { * status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getDistributionSets( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -77,8 +77,8 @@ public interface MgmtDistributionSetRestApi { * @return a single DistributionSet with status OK. * */ - @GetMapping(value = "/{distributionSetId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getDistributionSet(@PathVariable("distributionSetId") Long distributionSetId); /** @@ -92,8 +92,9 @@ public interface MgmtDistributionSetRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createDistributionSets(List sets); /** @@ -104,7 +105,7 @@ public interface MgmtDistributionSetRestApi { * @return status OK if delete as successful. * */ - @DeleteMapping(value = "/{distributionSetId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}") ResponseEntity deleteDistributionSet(@PathVariable("distributionSetId") Long distributionSetId); /** @@ -118,9 +119,9 @@ public interface MgmtDistributionSetRestApi { * @return status OK if update as successful with updated content. * */ - @PutMapping(value = "/{distributionSetId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE, - MediaTypes.HAL_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + "/{distributionSetId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { + MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE }) ResponseEntity updateDistributionSet(@PathVariable("distributionSetId") Long distributionSetId, MgmtDistributionSetRequestBodyPut toUpdate); @@ -146,8 +147,9 @@ public interface MgmtDistributionSetRestApi { * @return status OK if get request is successful with the paged list of * targets */ - @GetMapping(value = "/{distributionSetId}/assignedTargets", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/assignedTargets", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getAssignedTargets(@PathVariable("distributionSetId") Long distributionSetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -176,8 +178,9 @@ public interface MgmtDistributionSetRestApi { * @return status OK if get request is successful with the paged list of * targets */ - @GetMapping(value = "/{distributionSetId}/installedTargets", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/installedTargets", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getInstalledTargets(@PathVariable("distributionSetId") Long distributionSetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -206,8 +209,9 @@ public interface MgmtDistributionSetRestApi { * @return status OK if get request is successful with the paged list of * targets */ - @GetMapping(value = "/{distributionSetId}/autoAssignTargetFilters", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/autoAssignTargetFilters", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getAutoAssignTargetFilterQueries( @PathVariable("distributionSetId") Long distributionSetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @@ -231,9 +235,10 @@ public interface MgmtDistributionSetRestApi { * complex return body which contains information about the assigned * targets and the already assigned targets counters */ - @PostMapping(value = "/{distributionSetId}/assignedTargets", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/assignedTargets", consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity createAssignedTarget( @PathVariable("distributionSetId") Long distributionSetId, final List targetIds, @@ -259,8 +264,9 @@ public interface MgmtDistributionSetRestApi { * @return status OK if get request is successful with the paged list of * meta data */ - @GetMapping(value = "/{distributionSetId}/metadata", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/metadata", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getMetadata(@PathVariable("distributionSetId") Long distributionSetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -277,7 +283,8 @@ public interface MgmtDistributionSetRestApi { * @return status OK if get request is successful with the value of the meta * data */ - @GetMapping(value = "/{distributionSetId}/metadata/{metadataKey}", produces = { MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/metadata/{metadataKey}", produces = { MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getMetadataValue(@PathVariable("distributionSetId") Long distributionSetId, @PathVariable("metadataKey") String metadataKey); @@ -293,8 +300,9 @@ public interface MgmtDistributionSetRestApi { * @return status OK if the update request is successful and the updated * meta data result */ - @PutMapping(value = "/{distributionSetId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateMetadata(@PathVariable("distributionSetId") Long distributionSetId, @PathVariable("metadataKey") String metadataKey, MgmtMetadataBodyPut metadata); @@ -307,7 +315,8 @@ public interface MgmtDistributionSetRestApi { * the key of the meta data to delete * @return status OK if the delete request is successful */ - @DeleteMapping(value = "/{distributionSetId}/metadata/{metadataKey}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/metadata/{metadataKey}") ResponseEntity deleteMetadata(@PathVariable("distributionSetId") Long distributionSetId, @PathVariable("metadataKey") String metadataKey); @@ -321,8 +330,10 @@ public interface MgmtDistributionSetRestApi { * @return status created if post request is successful with the value of * the created meta data */ - @PostMapping(value = "/{distributionSetId}/metadata", consumes = { MediaType.APPLICATION_JSON_VALUE, - MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/metadata", consumes = { MediaType.APPLICATION_JSON_VALUE, + MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createMetadata(@PathVariable("distributionSetId") Long distributionSetId, List metadataRest); @@ -336,8 +347,10 @@ public interface MgmtDistributionSetRestApi { * @return http status * */ - @PostMapping(value = "/{distributionSetId}/assignedSM", consumes = { MediaType.APPLICATION_JSON_VALUE, - MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/assignedSM", consumes = { MediaType.APPLICATION_JSON_VALUE, + MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity assignSoftwareModules(@PathVariable("distributionSetId") Long distributionSetId, List softwareModuleIDs); @@ -352,7 +365,8 @@ public interface MgmtDistributionSetRestApi { * set * @return status OK if rejection was successful. */ - @DeleteMapping(value = "/{distributionSetId}/assignedSM/{softwareModuleId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/assignedSM/{softwareModuleId}") ResponseEntity deleteAssignSoftwareModules(@PathVariable("distributionSetId") Long distributionSetId, @PathVariable("softwareModuleId") Long softwareModuleId); @@ -374,8 +388,9 @@ public interface MgmtDistributionSetRestApi { * @return a list of the assigned software modules of a distribution set * with status OK, if none is assigned than {@code null} */ - @GetMapping(value = "/{distributionSetId}/assignedSM", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/assignedSM", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getAssignedSoftwareModules( @PathVariable("distributionSetId") Long distributionSetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @@ -391,9 +406,10 @@ public interface MgmtDistributionSetRestApi { * the definition if rollouts and actions should be canceled * @return status OK if the invalidation was successful */ - @PostMapping(value = "/{distributionSetId}/invalidate", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_V1_REQUEST_MAPPING + + "/{distributionSetId}/invalidate", consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity invalidateDistributionSet(@PathVariable("distributionSetId") Long distributionSetId, @Valid MgmtInvalidateDistributionSetRequestBody invalidateRequestBody); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java index a40f0055d..e8fd2842b 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTagRestApi.java @@ -24,15 +24,14 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling for DistributionSetTag CRUD operations. - * */ -@RequestMapping(MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtDistributionSetTagRestApi { + /** * Handles the GET request of retrieving all DistributionSet tags. * @@ -53,7 +52,8 @@ public interface MgmtDistributionSetTagRestApi { * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING, produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getDistributionSetTags( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -68,22 +68,23 @@ public interface MgmtDistributionSetTagRestApi { * * @return a single distribution set tag with status OK. */ - @GetMapping(value = "/{distributionsetTagId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + "/{distributionsetTagId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getDistributionSetTag(@PathVariable("distributionsetTagId") Long distributionsetTagId); /** - * Handles the POST request of creating new distribution set tag. The request - * body must always be a list of tags. + * 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 contains the created - * distribution set tags but without details. + * @return In case all modules could successful created the ResponseEntity + * with status code 201 - Created. The Response Body contains the + * created distribution set tags but without details. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING, consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createDistributionSetTags(List tags); /** @@ -94,12 +95,13 @@ public interface MgmtDistributionSetTagRestApi { * the ID of the distribution set tag * @param restDSTagRest * the request body to be updated - * @return status OK if update is successful and the updated distribution set - * tag. + * @return status OK if update is successful and the updated distribution + * set tag. */ - @PutMapping(value = "/{distributionsetTagId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + "/{distributionsetTagId}", consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateDistributionSetTag(@PathVariable("distributionsetTagId") Long distributionsetTagId, MgmtTagRequestBodyPut restDSTagRest); @@ -111,7 +113,7 @@ public interface MgmtDistributionSetTagRestApi { * @return status OK if delete as successfully. * */ - @DeleteMapping(value = "/{distributionsetTagId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + "/{distributionsetTagId}") ResponseEntity deleteDistributionSetTag(@PathVariable("distributionsetTagId") Long distributionsetTagId); /** @@ -135,8 +137,9 @@ public interface MgmtDistributionSetTagRestApi { * * @return the list of assigned distribution sets. */ - @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING, produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getAssignedDistributionSets( @PathVariable("distributionsetTagId") Long distributionsetTagId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @@ -156,8 +159,8 @@ public interface MgmtDistributionSetTagRestApi { * @return the list of assigned distribution sets and unassigned * distribution sets. */ - @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING - + "/toggleTagAssignment") + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING + "/toggleTagAssignment") ResponseEntity toggleTagAssignment( @PathVariable("distributionsetTagId") Long distributionsetTagId, List assignedDSRequestBodies); @@ -172,9 +175,10 @@ public interface MgmtDistributionSetTagRestApi { * * @return the list of assigned distribution set. */ - @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING, consumes = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING, consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> assignDistributionSets( @PathVariable("distributionsetTagId") Long distributionsetTagId, List assignedDSRequestBodies); @@ -189,8 +193,8 @@ public interface MgmtDistributionSetTagRestApi { * the ID of the distribution set to unassign * @return http status code */ - @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING - + "/{distributionsetId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.DISTRIBUTIONSET_TAG_DISTRIBUTIONSETS_REQUEST_MAPPING + "/{distributionsetId}") ResponseEntity unassignDistributionSet(@PathVariable("distributionsetTagId") Long distributionsetTagId, @PathVariable("distributionsetId") Long distributionsetId); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTypeRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTypeRestApi.java index 26c8753db..0549a4148 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTypeRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDistributionSetTypeRestApi.java @@ -24,14 +24,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling for DistributionSet CRUD operations. - * */ -@RequestMapping(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtDistributionSetTypeRestApi { /** @@ -55,7 +53,8 @@ public interface MgmtDistributionSetTypeRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING, produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getDistributionSetTypes( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -71,8 +70,8 @@ public interface MgmtDistributionSetTypeRestApi { * * @return a single DS type with status OK. */ - @GetMapping(value = "/{distributionSetTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + + "/{distributionSetTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getDistributionSetType( @PathVariable("distributionSetTypeId") Long distributionSetTypeId); @@ -84,7 +83,7 @@ public interface MgmtDistributionSetTypeRestApi { * @return status OK if delete is successful. * */ - @DeleteMapping(value = "/{distributionSetTypeId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}") ResponseEntity deleteDistributionSetType(@PathVariable("distributionSetTypeId") Long distributionSetTypeId); /** @@ -96,9 +95,10 @@ public interface MgmtDistributionSetTypeRestApi { * the DS type to be updated. * @return status OK if update is successful */ - @PutMapping(value = "/{distributionSetTypeId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + + "/{distributionSetTypeId}", consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateDistributionSetType( @PathVariable("distributionSetTypeId") Long distributionSetTypeId, MgmtDistributionSetTypeRequestBodyPut restDistributionSetType); @@ -114,8 +114,9 @@ public interface MgmtDistributionSetTypeRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING, consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createDistributionSetTypes( List distributionSetTypes); @@ -127,7 +128,7 @@ public interface MgmtDistributionSetTypeRestApi { * of the DistributionSetType. * @return Unpaged list of module types and OK in case of success. */ - @GetMapping(value = "/{distributionSetTypeId}/" + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getMandatoryModules( @@ -143,7 +144,8 @@ public interface MgmtDistributionSetTypeRestApi { * of SoftwareModuleType. * @return Unpaged list of module types and OK in case of success. */ - @GetMapping(value = "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES + "/{softwareModuleTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getMandatoryModule( @PathVariable("distributionSetTypeId") Long distributionSetTypeId, @@ -159,7 +161,8 @@ public interface MgmtDistributionSetTypeRestApi { * of SoftwareModuleType. * @return Unpaged list of module types and OK in case of success. */ - @GetMapping(value = "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES + "/{softwareModuleTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getOptionalModule( @PathVariable("distributionSetTypeId") Long distributionSetTypeId, @@ -173,7 +176,7 @@ public interface MgmtDistributionSetTypeRestApi { * of the DistributionSetType. * @return Unpaged list of module types and OK in case of success. */ - @GetMapping(value = "/{distributionSetTypeId}/" + @GetMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getOptionalModules( @@ -190,8 +193,8 @@ public interface MgmtDistributionSetTypeRestApi { * * @return OK if the request was successful */ - @DeleteMapping(value = "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES - + "/{softwareModuleTypeId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES + "/{softwareModuleTypeId}") ResponseEntity removeMandatoryModule(@PathVariable("distributionSetTypeId") Long distributionSetTypeId, @PathVariable("softwareModuleTypeId") Long softwareModuleTypeId); @@ -206,8 +209,8 @@ public interface MgmtDistributionSetTypeRestApi { * * @return OK if the request was successful */ - @DeleteMapping(value = "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES - + "/{softwareModuleTypeId}") + @DeleteMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES + "/{softwareModuleTypeId}") ResponseEntity removeOptionalModule(@PathVariable("distributionSetTypeId") Long distributionSetTypeId, @PathVariable("softwareModuleTypeId") Long softwareModuleTypeId); @@ -222,7 +225,7 @@ public interface MgmtDistributionSetTypeRestApi { * * @return OK if the request was successful */ - @PostMapping(value = "/{distributionSetTypeId}/" + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULE_TYPES, consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity addMandatoryModule(@PathVariable("distributionSetTypeId") Long distributionSetTypeId, @@ -239,7 +242,7 @@ public interface MgmtDistributionSetTypeRestApi { * * @return OK if the request was successful */ - @PostMapping(value = "/{distributionSetTypeId}/" + @PostMapping(value = MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_REQUEST_MAPPING + "/{distributionSetTypeId}/" + MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULE_TYPES, consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity addOptionalModule(@PathVariable("distributionSetTypeId") Long distributionSetTypeId, diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java index d0320e108..19682e2ed 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java @@ -13,14 +13,13 @@ import java.io.InputStream; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** - * + * API to download artifacts */ -@RequestMapping(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) @FunctionalInterface +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtDownloadArtifactRestApi { /** @@ -37,7 +36,8 @@ public interface MgmtDownloadArtifactRestApi { * * @return responseEntity with status ok if successful */ - @GetMapping(value = "/{softwareModuleId}/artifacts/{artifactId}/download") + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/artifacts/{artifactId}/download") @ResponseBody ResponseEntity downloadArtifact(@PathVariable("softwareModuleId") Long softwareModuleId, @PathVariable("artifactId") Long artifactId); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java index 9fa7b9333..b994b7750 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java @@ -14,15 +14,13 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; /** * A resource for download artifacts. - * */ -@RequestMapping(MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE) @FunctionalInterface +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtDownloadRestApi { /** @@ -37,7 +35,8 @@ public interface MgmtDownloadRestApi { * @return {@link ResponseEntity} with status {@link HttpStatus#OK} if * successful */ - @GetMapping(value = MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING) + @GetMapping(value = MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE + + MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING) @ResponseBody ResponseEntity downloadArtifactByDownloadId(@PathVariable("tenant") String tenant, @PathVariable("downloadId") String downloadId); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRestConstants.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRestConstants.java index af35a48bf..009eb5b1d 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRestConstants.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRestConstants.java @@ -44,7 +44,7 @@ public final class MgmtRestConstants { */ public static final String SOFTWAREMODULE_V1_REQUEST_MAPPING = BASE_V1_REQUEST_MAPPING + "/softwaremodules"; - public static final String DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE = "/api/" + API_VERSION + "/downloadserver/"; + public static final String DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE = "/api/" + API_VERSION + "/downloadserver"; public static final String DOWNLOAD_ID_V1_REQUEST_MAPPING = "/downloadId/{tenant}/{downloadId}"; diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java index 55c7f777d..df789622b 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtRolloutRestApi.java @@ -20,14 +20,12 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling rollout CRUD operations. - * */ -@RequestMapping(MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtRolloutRestApi { /** @@ -52,7 +50,8 @@ public interface MgmtRolloutRestApi { * status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getRollouts( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @@ -67,7 +66,8 @@ public interface MgmtRolloutRestApi { * the ID of the rollout to retrieve * @return a single rollout with status OK. */ - @GetMapping(value = "/{rolloutId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getRollout(@PathVariable("rolloutId") Long rolloutId); /** @@ -80,8 +80,9 @@ public interface MgmtRolloutRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity create(MgmtRolloutRestRequestBody rolloutRequestBody); /** @@ -94,8 +95,8 @@ public interface MgmtRolloutRestApi { * @return OK response (200) if rollout is approved now. In case of any * exception the corresponding errors occur. */ - @PostMapping(value = "/{rolloutId}/approve", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/approve", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity approve(@PathVariable("rolloutId") Long rolloutId, @RequestParam(value = "remark", required = false) String remark); @@ -109,8 +110,8 @@ public interface MgmtRolloutRestApi { * @return OK response (200) if rollout is denied now. In case of any * exception the corresponding errors occur. */ - @PostMapping(value = "/{rolloutId}/deny", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/deny", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity deny(@PathVariable("rolloutId") Long rolloutId, @RequestParam(value = "remark", required = false) String remark); @@ -122,8 +123,8 @@ public interface MgmtRolloutRestApi { * @return OK response (200) if rollout could be started. In case of any * exception the corresponding errors occur. */ - @PostMapping(value = "/{rolloutId}/start", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/start", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity start(@PathVariable("rolloutId") Long rolloutId); /** @@ -134,8 +135,8 @@ public interface MgmtRolloutRestApi { * @return OK response (200) if rollout could be paused. In case of any * exception the corresponding errors occur. */ - @PostMapping(value = "/{rolloutId}/pause", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/pause", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity pause(@PathVariable("rolloutId") Long rolloutId); /** @@ -146,7 +147,8 @@ public interface MgmtRolloutRestApi { * @return OK response (200) if rollout could be deleted. In case of any * exception the corresponding errors occur. */ - @DeleteMapping(value = "/{rolloutId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @DeleteMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity delete(@PathVariable("rolloutId") Long rolloutId); /** @@ -157,8 +159,8 @@ public interface MgmtRolloutRestApi { * @return OK response (200) if rollout could be resumed. In case of any * exception the corresponding errors occur. */ - @PostMapping(value = "/{rolloutId}/resume", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/resume", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity resume(@PathVariable("rolloutId") Long rolloutId); /** @@ -183,8 +185,8 @@ public interface MgmtRolloutRestApi { * paged. In any failure the JsonResponseExceptionHandler is * handling the response. */ - @GetMapping(value = "/{rolloutId}/deploygroups", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/deploygroups", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getRolloutGroups(@PathVariable("rolloutId") Long rolloutId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -200,8 +202,9 @@ public interface MgmtRolloutRestApi { * the groupId to retrieve the rollout group * @return the OK response containing the MgmtRolloutGroupResponseBody */ - @GetMapping(value = "/{rolloutId}/deploygroups/{groupId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + + "/{rolloutId}/deploygroups/{groupId}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getRolloutGroup(@PathVariable("rolloutId") Long rolloutId, @PathVariable("groupId") Long groupId); @@ -228,8 +231,9 @@ public interface MgmtRolloutRestApi { * @return a paged list of targets related to a specific rollout and rollout * group. */ - @GetMapping(value = "/{rolloutId}/deploygroups/{groupId}/targets", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + + "/{rolloutId}/deploygroups/{groupId}/targets", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getRolloutGroupTargets(@PathVariable("rolloutId") Long rolloutId, @PathVariable("groupId") Long groupId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @@ -238,14 +242,15 @@ public interface MgmtRolloutRestApi { @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_SEARCH, required = false) String rsqlParam); /** - * Handles the POST request to force trigger processing next group of a rollout even success threshold isn't yet met + * Handles the POST request to force trigger processing next group of a + * rollout even success threshold isn't yet met * * @param rolloutId * the ID of the rollout to trigger next group. - * @return OK response (200). In case of any - * exception the corresponding errors occur. + * @return OK response (200). In case of any exception the corresponding + * errors occur. */ - @PostMapping(value = "/{rolloutId}/triggerNextGroup", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.ROLLOUT_V1_REQUEST_MAPPING + "/{rolloutId}/triggerNextGroup", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity triggerNextGroup(@PathVariable("rolloutId") Long rolloutId); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleRestApi.java index 68ad7ea3b..f6746474b 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleRestApi.java @@ -25,7 +25,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.ResponseBody; @@ -34,9 +33,8 @@ import org.springframework.web.multipart.MultipartFile; /** * REST Resource handling for SoftwareModule and related Artifact CRUD * operations. - * */ -@RequestMapping(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtSoftwareModuleRestApi { /** @@ -60,8 +58,9 @@ public interface MgmtSoftwareModuleRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(value = "/{softwareModuleId}/artifacts", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/artifacts", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity uploadArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, @RequestPart("file") final MultipartFile file, @RequestParam(value = "filename", required = false) final String optionalFileName, @@ -80,8 +79,9 @@ public interface MgmtSoftwareModuleRestApi { * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(value = "/{softwareModuleId}/artifacts", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/artifacts", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getArtifacts(@PathVariable("softwareModuleId") final Long softwareModuleId); /** @@ -95,8 +95,9 @@ public interface MgmtSoftwareModuleRestApi { * * @return responseEntity with status ok if successful */ - @GetMapping(value = "/{softwareModuleId}/artifacts/{artifactId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/artifacts/{artifactId}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) @ResponseBody ResponseEntity getArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("artifactId") final Long artifactId); @@ -111,7 +112,8 @@ public interface MgmtSoftwareModuleRestApi { * * @return status OK if delete as successful. */ - @DeleteMapping(value = "/{softwareModuleId}/artifacts/{artifactId}") + @DeleteMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/artifacts/{artifactId}") @ResponseBody ResponseEntity deleteArtifact(@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("artifactId") final Long artifactId); @@ -136,7 +138,8 @@ public interface MgmtSoftwareModuleRestApi { * status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getSoftwareModules( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) final int pagingLimitParam, @@ -151,8 +154,8 @@ public interface MgmtSoftwareModuleRestApi { * * @return a single softwareModule with status OK. */ - @GetMapping(value = "/{softwareModuleId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getSoftwareModule(@PathVariable("softwareModuleId") final Long softwareModuleId); /** @@ -166,8 +169,9 @@ public interface MgmtSoftwareModuleRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createSoftwareModules( final List softwareModules); @@ -180,8 +184,8 @@ public interface MgmtSoftwareModuleRestApi { * the modules to be updated. * @return status OK if update was successful */ - @PutMapping(value = "/{softwareModuleId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateSoftwareModule( @PathVariable("softwareModuleId") final Long softwareModuleId, @@ -195,7 +199,7 @@ public interface MgmtSoftwareModuleRestApi { * @return status OK if delete was successful. * */ - @DeleteMapping(value = "/{softwareModuleId}") + @DeleteMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + "/{softwareModuleId}") ResponseEntity deleteSoftwareModule(@PathVariable("softwareModuleId") final Long softwareModuleId); /** @@ -218,8 +222,9 @@ public interface MgmtSoftwareModuleRestApi { * @return status OK if get request is successful with the paged list of * meta data */ - @GetMapping(value = "/{softwareModuleId}/metadata", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/metadata", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getMetadata( @PathVariable("softwareModuleId") final Long softwareModuleId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @@ -237,8 +242,9 @@ public interface MgmtSoftwareModuleRestApi { * @return status OK if get request is successful with the value of the meta * data */ - @GetMapping(value = "/{softwareModuleId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getMetadataValue( @PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("metadataKey") final String metadataKey); @@ -255,8 +261,9 @@ public interface MgmtSoftwareModuleRestApi { * @return status OK if the update request is successful and the updated * meta data result */ - @PutMapping(value = "/{softwareModuleId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateMetadata( @PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("metadataKey") final String metadataKey, final MgmtSoftwareModuleMetadataBodyPut metadata); @@ -270,7 +277,8 @@ public interface MgmtSoftwareModuleRestApi { * the key of the meta data to delete * @return status OK if the delete request is successful */ - @DeleteMapping(value = "/{softwareModuleId}/metadata/{metadataKey}") + @DeleteMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/metadata/{metadataKey}") ResponseEntity deleteMetadata(@PathVariable("softwareModuleId") final Long softwareModuleId, @PathVariable("metadataKey") final String metadataKey); @@ -284,8 +292,10 @@ public interface MgmtSoftwareModuleRestApi { * @return status created if post request is successful with the value of * the created meta data */ - @PostMapping(value = "/{softwareModuleId}/metadata", consumes = { MediaType.APPLICATION_JSON_VALUE, - MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING + + "/{softwareModuleId}/metadata", consumes = { MediaType.APPLICATION_JSON_VALUE, + MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createMetadata( @PathVariable("softwareModuleId") final Long softwareModuleId, final List metadataRest); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleTypeRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleTypeRestApi.java index b2d608739..efb8492e8 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleTypeRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSoftwareModuleTypeRestApi.java @@ -22,16 +22,15 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling for SoftwareModule and related Artifact CRUD * operations. - * */ -@RequestMapping(MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtSoftwareModuleTypeRestApi { + /** * Handles the GET request of retrieving all SoftwareModuleTypes . * @@ -52,7 +51,8 @@ public interface MgmtSoftwareModuleTypeRestApi { * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getTypes( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -67,8 +67,8 @@ public interface MgmtSoftwareModuleTypeRestApi { * * @return a single softwareModule with status OK. */ - @GetMapping(value = "/{softwareModuleTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING + + "/{softwareModuleTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getSoftwareModuleType( @PathVariable("softwareModuleTypeId") Long softwareModuleTypeId); @@ -80,7 +80,7 @@ public interface MgmtSoftwareModuleTypeRestApi { * @return status OK if delete as successfully. * */ - @DeleteMapping(value = "/{softwareModuleTypeId}") + @DeleteMapping(value = MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING + "/{softwareModuleTypeId}") ResponseEntity deleteSoftwareModuleType(@PathVariable("softwareModuleTypeId") Long softwareModuleTypeId); /** @@ -92,9 +92,10 @@ public interface MgmtSoftwareModuleTypeRestApi { * the module type to be updated. * @return status OK if update is successful */ - @PutMapping(value = "/{softwareModuleTypeId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING + + "/{softwareModuleTypeId}", consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateSoftwareModuleType( @PathVariable("softwareModuleTypeId") Long softwareModuleTypeId, MgmtSoftwareModuleTypeRequestBodyPut restSoftwareModuleType); @@ -110,8 +111,9 @@ public interface MgmtSoftwareModuleTypeRestApi { * failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.SOFTWAREMODULETYPE_V1_REQUEST_MAPPING, consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createSoftwareModuleTypes( List softwareModuleTypes); diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSystemManagementRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSystemManagementRestApi.java index c5b5cb3eb..735e5f7c5 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSystemManagementRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtSystemManagementRestApi.java @@ -18,13 +18,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; /** * System management capabilities by REST. - * */ -@RequestMapping(MgmtRestConstants.SYSTEM_ADMIN_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtSystemManagementRestApi { /** @@ -34,7 +32,7 @@ public interface MgmtSystemManagementRestApi { * to delete * @return HttpStatus.OK */ - @DeleteMapping(value = "/tenants/{tenant}") + @DeleteMapping(value = MgmtRestConstants.SYSTEM_ADMIN_MAPPING + "/tenants/{tenant}") ResponseEntity deleteTenant(@PathVariable("tenant") String tenant); /** @@ -43,7 +41,8 @@ public interface MgmtSystemManagementRestApi { * * @return system usage statistics */ - @GetMapping(value = "/usage", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SYSTEM_ADMIN_MAPPING + "/usage", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getSystemUsageStats(); /** @@ -51,7 +50,8 @@ public interface MgmtSystemManagementRestApi { * * @return a list of caches for all tenants */ - @GetMapping(value = "/caches", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SYSTEM_ADMIN_MAPPING + "/caches", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getCaches(); /** @@ -59,7 +59,7 @@ public interface MgmtSystemManagementRestApi { * * @return a list of cache names which has been invalidated */ - @DeleteMapping(value = "/caches") + @DeleteMapping(value = MgmtRestConstants.SYSTEM_ADMIN_MAPPING + "/caches") ResponseEntity> invalidateCaches(); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetFilterQueryRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetFilterQueryRestApi.java index 8c8703d4a..e4993e832 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetFilterQueryRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetFilterQueryRestApi.java @@ -22,13 +22,12 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * Api for handling target operations. */ -@RequestMapping(MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtTargetFilterQueryRestApi { /** @@ -39,7 +38,8 @@ public interface MgmtTargetFilterQueryRestApi { * @return a single target with status OK. */ - @GetMapping(value = "/{filterId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{filterId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getFilter(@PathVariable("filterId") Long filterId); /** @@ -62,7 +62,8 @@ public interface MgmtTargetFilterQueryRestApi { * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getFilters( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -80,8 +81,9 @@ public interface MgmtTargetFilterQueryRestApi { * is returned. In any failure the JsonResponseExceptionHandler is * handling the response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity createFilter(@RequestBody MgmtTargetFilterQueryRequestBody filter); /** @@ -98,8 +100,8 @@ public interface MgmtTargetFilterQueryRestApi { * @return the updated target filter response which contains all fields * including fields which have not been updated */ - @PutMapping(value = "/{filterId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{filterId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateFilter(@PathVariable("filterId") Long filterId, @RequestBody MgmtTargetFilterQueryRequestBody targetFilterRest); @@ -113,7 +115,8 @@ public interface MgmtTargetFilterQueryRestApi { * OK. In any failure the JsonResponseExceptionHandler is handling * the response. */ - @DeleteMapping(value = "/{filterId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @DeleteMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{filterId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity deleteFilter(@PathVariable("filterId") Long filterId); /** @@ -125,8 +128,8 @@ public interface MgmtTargetFilterQueryRestApi { * @return the assigned distribution set with status OK, if none is assigned * than {@code null} content (e.g. "{}") */ - @GetMapping(value = "/{filterId}/autoAssignDS", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{filterId}/autoAssignDS", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getAssignedDistributionSet(@PathVariable("filterId") Long filterId); /** @@ -140,8 +143,8 @@ public interface MgmtTargetFilterQueryRestApi { * assignment * @return http status */ - @PostMapping(value = "/{filterId}/autoAssignDS", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PostMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{filterId}/autoAssignDS", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity postAssignedDistributionSet(@PathVariable("filterId") Long filterId, @RequestBody MgmtDistributionSetAutoAssignment dsIdWithActionType); @@ -154,7 +157,7 @@ public interface MgmtTargetFilterQueryRestApi { * of the target to change * @return http status */ - @DeleteMapping(value = "/{filterId}/autoAssignDS") + @DeleteMapping(value = MgmtRestConstants.TARGET_FILTER_V1_REQUEST_MAPPING + "/{filterId}/autoAssignDS") ResponseEntity deleteAssignedDistributionSet(@PathVariable("filterId") Long filterId); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java index c88ae33af..f74c870cd 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetRestApi.java @@ -34,13 +34,12 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** - * Api for handling target operations. + * API for handling target operations. */ -@RequestMapping(MgmtRestConstants.TARGET_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtTargetRestApi { /** @@ -50,7 +49,8 @@ public interface MgmtTargetRestApi { * the ID of the target to retrieve * @return a single target with status OK. */ - @GetMapping(value = "/{targetId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getTarget(@PathVariable("targetId") String targetId); /** @@ -73,7 +73,8 @@ public interface MgmtTargetRestApi { * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getTargets( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -91,8 +92,9 @@ public interface MgmtTargetRestApi { * entities. In any failure the JsonResponseExceptionHandler is * handling the response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createTargets(List targets); /** @@ -109,8 +111,8 @@ public interface MgmtTargetRestApi { * @return the updated target response which contains all fields also fields * which have not updated */ - @PutMapping(value = "/{targetId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateTarget(@PathVariable("targetId") String targetId, MgmtTargetRequestBody targetRest); @@ -124,7 +126,7 @@ public interface MgmtTargetRestApi { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @DeleteMapping(value = "/{targetId}") + @DeleteMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}") ResponseEntity deleteTarget(@PathVariable("targetId") String targetId); /** @@ -136,7 +138,8 @@ public interface MgmtTargetRestApi { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @DeleteMapping(value = MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING) + @DeleteMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING) ResponseEntity unassignTargetType(@PathVariable("targetId") String targetId); /** @@ -148,8 +151,9 @@ public interface MgmtTargetRestApi { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @PostMapping(value = MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TARGET_TYPE_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity assignTargetType(@PathVariable("targetId") String targetId, MgmtId targetTypeId); /** @@ -160,8 +164,8 @@ public interface MgmtTargetRestApi { * the ID of the target to retrieve the attributes. * @return the target attributes as map response with status OK */ - @GetMapping(value = "/{targetId}/attributes", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/attributes", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getAttributes(@PathVariable("targetId") String targetId); /** @@ -185,8 +189,8 @@ public interface MgmtTargetRestApi { * status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(value = "/{targetId}/actions", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getActionHistory(@PathVariable("targetId") String targetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -203,8 +207,8 @@ public interface MgmtTargetRestApi { * to load * @return the action */ - @GetMapping(value = "/{targetId}/actions/{actionId}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getAction(@PathVariable("targetId") String targetId, @PathVariable("actionId") Long actionId); @@ -220,7 +224,7 @@ public interface MgmtTargetRestApi { * optional parameter, which indicates a force cancel * @return status no content in case cancellation was successful */ - @DeleteMapping(value = "/{targetId}/actions/{actionId}") + @DeleteMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}") ResponseEntity cancelAction(@PathVariable("targetId") String targetId, @PathVariable("actionId") Long actionId, @RequestParam(value = "force", required = false, defaultValue = "false") boolean force); @@ -236,8 +240,8 @@ public interface MgmtTargetRestApi { * to update the action * @return status no content in case cancellation was successful */ - @PutMapping(value = "/{targetId}/actions/{actionId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/actions/{actionId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateAction(@PathVariable("targetId") String targetId, @PathVariable("actionId") Long actionId, MgmtActionRequestBodyPut actionUpdate); @@ -263,8 +267,9 @@ public interface MgmtTargetRestApi { * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(value = "/{targetId}/actions/{actionId}/status", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + + "/{targetId}/actions/{actionId}/status", produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getActionStatusList(@PathVariable("targetId") String targetId, @PathVariable("actionId") Long actionId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @@ -281,8 +286,8 @@ public interface MgmtTargetRestApi { * @return the assigned distribution set with status OK, if none is assigned * than {@code null} content (e.g. "{}") */ - @GetMapping(value = "/{targetId}/assignedDS", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/assignedDS", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getAssignedDistributionSet(@PathVariable("targetId") String targetId); /** @@ -300,8 +305,8 @@ public interface MgmtTargetRestApi { * complex return body which contains information about the assigned * targets and the already assigned targets counters */ - @PostMapping(value = "/{targetId}/assignedDS", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/assignedDS", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity postAssignedDistributionSet( @PathVariable("targetId") String targetId, MgmtDistributionSetAssignments dsAssignments, @@ -316,8 +321,8 @@ public interface MgmtTargetRestApi { * @return the assigned installed set with status OK, if none is installed * than {@code null} content (e.g. "{}") */ - @GetMapping(value = "/{targetId}/installedDS", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/installedDS", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getInstalledDistributionSet(@PathVariable("targetId") String targetId); /** @@ -340,8 +345,8 @@ public interface MgmtTargetRestApi { * @return status OK if get request is successful with the paged list of * meta data */ - @GetMapping(value = "/{targetId}/metadata", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getMetadata(@PathVariable("targetId") String targetId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -358,7 +363,8 @@ public interface MgmtTargetRestApi { * @return status OK if get request is successful with the value of the meta * data */ - @GetMapping(value = "/{targetId}/metadata/{metadataKey}", produces = { MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata/{metadataKey}", produces = { + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getMetadataValue(@PathVariable("targetId") String targetId, @PathVariable("metadataKey") String metadataKey); @@ -374,8 +380,8 @@ public interface MgmtTargetRestApi { * @return status OK if the update request is successful and the updated * meta data result */ - @PutMapping(value = "/{targetId}/metadata/{metadataKey}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PutMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata/{metadataKey}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateMetadata(@PathVariable("targetId") String targetId, @PathVariable("metadataKey") String metadataKey, MgmtMetadataBodyPut metadata); @@ -388,7 +394,7 @@ public interface MgmtTargetRestApi { * the key of the meta data to delete * @return status OK if the delete request is successful */ - @DeleteMapping(value = "/{targetId}/metadata/{metadataKey}") + @DeleteMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata/{metadataKey}") ResponseEntity deleteMetadata(@PathVariable("targetId") String targetId, @PathVariable("metadataKey") String metadataKey); @@ -399,10 +405,11 @@ public interface MgmtTargetRestApi { * the ID of the targetId 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 + * @return status created if post request is successful with the value of + * the created meta data */ - @PostMapping(value = "/{targetId}/metadata", consumes = { MediaType.APPLICATION_JSON_VALUE, + @PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/metadata", consumes = { + MediaType.APPLICATION_JSON_VALUE, MediaTypes.HAL_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createMetadata(@PathVariable("targetId") String targetId, List metadataRest); @@ -414,8 +421,8 @@ public interface MgmtTargetRestApi { * to check the state for * @return the current state as {@link MgmtTargetAutoConfirm} */ - @GetMapping(value = "/{targetId}/autoConfirm", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/autoConfirm", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getAutoConfirmStatus(@PathVariable("targetId") String targetId); /** @@ -425,9 +432,10 @@ public interface MgmtTargetRestApi { * to activate auto-confirm on * @param update * properties to update - * @return {@link org.springframework.http.HttpStatus#OK} in case of a success + * @return {@link org.springframework.http.HttpStatus#OK} in case of a + * success */ - @PostMapping(value = "/{targetId}/autoConfirm/activate") + @PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/autoConfirm/activate") ResponseEntity activateAutoConfirm(@PathVariable("targetId") String targetId, @RequestBody(required = false) MgmtTargetAutoConfirmUpdate update); @@ -437,9 +445,10 @@ public interface MgmtTargetRestApi { * @param targetId * to deactivate auto-confirm on * - * @return {@link org.springframework.http.HttpStatus#OK} in case of a success + * @return {@link org.springframework.http.HttpStatus#OK} in case of a + * success */ - @PostMapping(value = "/{targetId}/autoConfirm/deactivate") + @PostMapping(value = MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/{targetId}/autoConfirm/deactivate") ResponseEntity deactivateAutoConfirm(@PathVariable("targetId") String targetId); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java index 30d6c7a34..ee60b9611 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTagRestApi.java @@ -24,14 +24,12 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling for TargetTag CRUD operations. - * */ -@RequestMapping(MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtTargetTagRestApi { /** @@ -53,7 +51,8 @@ public interface MgmtTargetTagRestApi { * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getTargetTags( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -68,7 +67,8 @@ public interface MgmtTargetTagRestApi { * * @return a single target tag with status OK. */ - @GetMapping(value = "/{targetTagId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getTargetTag(@PathVariable("targetTagId") Long targetTagId); /** @@ -81,8 +81,9 @@ public interface MgmtTargetTagRestApi { * with status code 201 - Created. The Response Body are the created * target tags but without ResponseBody. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createTargetTags(List tags); /** @@ -95,8 +96,8 @@ public interface MgmtTargetTagRestApi { * the the request body to be updated * @return status OK if update is successful and the updated target tag. */ - @PutMapping(value = "/{targetTagId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateTargetTag(@PathVariable("targetTagId") Long targetTagId, MgmtTagRequestBodyPut restTargetTagRest); @@ -109,7 +110,7 @@ public interface MgmtTargetTagRestApi { * @return status OK if delete as successfully. * */ - @DeleteMapping(value = "/{targetTagId}") + @DeleteMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + "/{targetTagId}") ResponseEntity deleteTargetTag(@PathVariable("targetTagId") Long targetTagId); /** @@ -133,8 +134,9 @@ public interface MgmtTargetTagRestApi { * * @return the list of assigned targets. */ - @GetMapping(value = MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getAssignedTargets(@PathVariable("targetTagId") Long targetTagId, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -152,9 +154,10 @@ public interface MgmtTargetTagRestApi { * * @return the list of assigned targets and unassigned targets. */ - @PostMapping(value = MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING + "/toggleTagAssignment", consumes = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING + "/toggleTagAssignment", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity toggleTagAssignment(@PathVariable("targetTagId") Long targetTagId, List assignedTargetRequestBodies); @@ -168,9 +171,10 @@ public interface MgmtTargetTagRestApi { * * @return the list of assigned targets. */ - @PostMapping(value = MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> assignTargets(@PathVariable("targetTagId") Long targetTagId, List assignedTargetRequestBodies); @@ -183,7 +187,8 @@ public interface MgmtTargetTagRestApi { * the ID of the target to unassign * @return http status code */ - @DeleteMapping(value = MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING + "/{controllerId}") + @DeleteMapping(value = MgmtRestConstants.TARGET_TAG_V1_REQUEST_MAPPING + + MgmtRestConstants.TARGET_TAG_TARGETS_REQUEST_MAPPING + "/{controllerId}") ResponseEntity unassignTarget(@PathVariable("targetTagId") Long targetTagId, @PathVariable("controllerId") String controllerId); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTypeRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTypeRestApi.java index f221e5248..074e1dee6 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTypeRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTargetTypeRestApi.java @@ -24,25 +24,24 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; /** * REST Resource handling for TargetType CRUD operations. - * */ -@RequestMapping(MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtTargetTypeRestApi { /** * Handles the GET request of retrieving all TargetTypes. * * @param pagingOffsetParam - * the offset of list of target types for pagination, might not be - * present in the rest request then default value will be applied + * the offset of list of target types 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 + * 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} @@ -50,11 +49,12 @@ public interface MgmtTargetTypeRestApi { * the search parameter in the request URL, syntax * {@code q=name==abc} * - * @return a list of all TargetTypes for a defined or default page request with - * status OK. The response is always paged. In any failure the + * @return a list of all TargetTypes for a defined or default page request + * with status OK. The response is always paged. In any failure the * JsonResponseExceptionHandler is handling the response. */ - @GetMapping(produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getTargetTypes( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) int pagingOffsetParam, @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_LIMIT, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT) int pagingLimitParam, @@ -69,7 +69,8 @@ public interface MgmtTargetTypeRestApi { * * @return a single target type with status OK. */ - @GetMapping(value = "/{targetTypeId}", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING + "/{targetTypeId}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getTargetType(@PathVariable("targetTypeId") Long targetTypeId); /** @@ -80,7 +81,7 @@ public interface MgmtTargetTypeRestApi { * @return status OK if delete is successful. * */ - @DeleteMapping(value = "/{targetTypeId}") + @DeleteMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING + "/{targetTypeId}") ResponseEntity deleteTargetType(@PathVariable("targetTypeId") Long targetTypeId); /** @@ -92,15 +93,15 @@ public interface MgmtTargetTypeRestApi { * the target type to be updated. * @return status OK if update is successful */ - @PutMapping(value = "/{targetTypeId}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING + "/{targetTypeId}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateTargetType(@PathVariable("targetTypeId") Long targetTypeId, MgmtTargetTypeRequestBodyPut restTargetType); /** - * Handles the POST request of creating new Target Types. The request body must - * always be a list of types. + * Handles the POST request of creating new Target Types. The request body + * must always be a list of types. * * @param targetTypes * the target types to be created. @@ -109,26 +110,28 @@ public interface MgmtTargetTypeRestApi { * ResponseBody. In any failure the JsonResponseExceptionHandler is * handling the response. */ - @PostMapping(consumes = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> createTargetTypes(List targetTypes); /** - * Handles the GET request of retrieving the list of compatible distribution set - * types in that target type. + * Handles the GET request of retrieving the list of compatible distribution + * set types in that target type. * * @param targetTypeId * of the TargetType. * @return Unpaged list of distribution set types and OK in case of success. */ - @GetMapping(value = "/{targetTypeId}/" + MgmtRestConstants.TARGETTYPE_V1_DS_TYPES, produces = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING + "/{targetTypeId}/" + + MgmtRestConstants.TARGETTYPE_V1_DS_TYPES, produces = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getCompatibleDistributionSets( @PathVariable("targetTypeId") Long targetTypeId); /** - * Handles DELETE request for removing the compatibility of a distribution set - * type from the target type. + * Handles DELETE request for removing the compatibility of a distribution + * set type from the target type. * * @param targetTypeId * of the TargetType. @@ -137,13 +140,14 @@ public interface MgmtTargetTypeRestApi { * * @return OK if the request was successful */ - @DeleteMapping(value = "/{targetTypeId}/" + MgmtRestConstants.TARGETTYPE_V1_DS_TYPES + "/{distributionSetTypeId}") + @DeleteMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING + "/{targetTypeId}/" + + MgmtRestConstants.TARGETTYPE_V1_DS_TYPES + "/{distributionSetTypeId}") ResponseEntity removeCompatibleDistributionSet(@PathVariable("targetTypeId") Long targetTypeId, @PathVariable("distributionSetTypeId") Long distributionSetTypeId); /** - * Handles the POST request for adding the compatibility of a distribution set - * type to a target type. + * Handles the POST request for adding the compatibility of a distribution + * set type to a target type. * * @param targetTypeId * of the TargetType. @@ -152,8 +156,9 @@ public interface MgmtTargetTypeRestApi { * * @return OK if the request was successful */ - @PostMapping(value = "/{targetTypeId}/" + MgmtRestConstants.TARGETTYPE_V1_DS_TYPES, consumes = { - MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @PostMapping(value = MgmtRestConstants.TARGETTYPE_V1_REQUEST_MAPPING + "/{targetTypeId}/" + + MgmtRestConstants.TARGETTYPE_V1_DS_TYPES, consumes = { MediaTypes.HAL_JSON_VALUE, + MediaType.APPLICATION_JSON_VALUE }) ResponseEntity addCompatibleDistributionSets(@PathVariable("targetTypeId") final Long targetTypeId, final List distributionSetTypeIds); } diff --git a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java index a1338a93d..dbfc9de48 100644 --- a/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java +++ b/hawkbit-rest/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtTenantManagementRestApi.java @@ -19,13 +19,11 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestMapping; /** * REST Resource for handling tenant specific configuration operations. - * */ -@RequestMapping(MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING) +// no request mapping specified here to avoid CVE-2021-22044 in Feign client public interface MgmtTenantManagementRestApi { /** @@ -34,7 +32,8 @@ public interface MgmtTenantManagementRestApi { * * @return a map of all configuration values. */ - @GetMapping(value = "/configs", produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity> getTenantConfiguration(); /** @@ -47,8 +46,8 @@ public interface MgmtTenantManagementRestApi { * OK. In any failure the JsonResponseExceptionHandler is handling * the response. */ - @DeleteMapping(value = "/configs/{keyName}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @DeleteMapping(value = MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity deleteTenantConfigurationValue(@PathVariable("keyName") String keyName); /** @@ -61,8 +60,8 @@ public interface MgmtTenantManagementRestApi { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @GetMapping(value = "/configs/{keyName}", produces = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }) + @GetMapping(value = MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", produces = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity getTenantConfigurationValue( @PathVariable("keyName") String keyName); @@ -78,8 +77,8 @@ public interface MgmtTenantManagementRestApi { * In any failure the JsonResponseExceptionHandler is handling the * response. */ - @PutMapping(value = "/configs/{keyName}", consumes = { MediaTypes.HAL_JSON_VALUE, - MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, + @PutMapping(value = MgmtRestConstants.SYSTEM_V1_REQUEST_MAPPING + "/configs/{keyName}", consumes = { + MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }, produces = { MediaTypes.HAL_JSON_VALUE, MediaType.APPLICATION_JSON_VALUE }) ResponseEntity updateTenantConfigurationValue( @PathVariable("keyName") String keyName, MgmtSystemTenantConfigurationValueRequest configurationValueRest); diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java index d1fe6d96d..c8750fc40 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetMapper.java @@ -119,7 +119,7 @@ public final class MgmtDistributionSetMapper { response.setRequiredMigrationStep(distributionSet.isRequiredMigrationStep()); response.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSet(response.getDsId())) - .withSelfRel()); + .withSelfRel().expand()); return response; } @@ -128,14 +128,15 @@ public final class MgmtDistributionSetMapper { response.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getAssignedSoftwareModules(response.getDsId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null)) - .withRel(MgmtRestConstants.DISTRIBUTIONSET_V1_MODULE)); + .withRel(MgmtRestConstants.DISTRIBUTIONSET_V1_MODULE).expand()); response.add(linkTo(methodOn(MgmtDistributionSetTypeRestApi.class) - .getDistributionSetType(distributionSet.getType().getId())).withRel("type")); + .getDistributionSetType(distributionSet.getType().getId())).withRel("type").expand()); response.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getMetadata(response.getDsId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, - MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata")); + MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata") + .expand()); } static MgmtTargetAssignmentResponseBody toResponse(final DistributionSetAssignmentResult dsAssignmentResult) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java index 21e921af0..ac6750add 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTypeMapper.java @@ -86,7 +86,7 @@ final class MgmtDistributionSetTypeMapper { result.setColour(type.getColour()); result.add(linkTo(methodOn(MgmtDistributionSetTypeRestApi.class).getDistributionSetType(result.getModuleId())) - .withSelfRel()); + .withSelfRel().expand()); return result; } @@ -94,10 +94,10 @@ final class MgmtDistributionSetTypeMapper { static void addLinks(final MgmtDistributionSetType result) { result.add(linkTo(methodOn(MgmtDistributionSetTypeRestApi.class).getMandatoryModules(result.getModuleId())) - .withRel(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULES)); + .withRel(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_MANDATORY_MODULES).expand()); result.add(linkTo(methodOn(MgmtDistributionSetTypeRestApi.class).getOptionalModules(result.getModuleId())) - .withRel(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULES)); + .withRel(MgmtRestConstants.DISTRIBUTIONSETTYPE_V1_OPTIONAL_MODULES).expand()); } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java index bc1c1ec5e..aa880f479 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutMapper.java @@ -95,22 +95,26 @@ final class MgmtRolloutMapper { body.setTotalGroups(rollout.getRolloutGroupsCreated()); body.setStartAt(rollout.getStartAt()); - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).start(rollout.getId())).withRel("start")); - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).pause(rollout.getId())).withRel("pause")); - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).resume(rollout.getId())).withRel("resume")); - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).triggerNextGroup(rollout.getId())).withRel("triggerNextGroup")); - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).approve(rollout.getId(), null)).withRel("approve")); - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).deny(rollout.getId(), null)).withRel("deny")); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).start(rollout.getId())).withRel("start").expand()); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).pause(rollout.getId())).withRel("pause").expand()); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).resume(rollout.getId())).withRel("resume").expand()); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).triggerNextGroup(rollout.getId())) + .withRel("triggerNextGroup").expand()); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).approve(rollout.getId(), null)).withRel("approve") + .expand()); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).deny(rollout.getId(), null)).withRel("deny").expand()); body.add(linkTo(methodOn(MgmtRolloutRestApi.class).getRolloutGroups(rollout.getId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, - MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("groups")); + MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("groups") + .expand()); final DistributionSet distributionSet = rollout.getDistributionSet(); body.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSet(distributionSet.getId())) - .withRel("distributionset").withName(distributionSet.getName() + ":" + distributionSet.getVersion())); + .withRel("distributionset").withName(distributionSet.getName() + ":" + distributionSet.getVersion()) + .expand()); } - body.add(linkTo(methodOn(MgmtRolloutRestApi.class).getRollout(rollout.getId())).withSelfRel()); + body.add(linkTo(methodOn(MgmtRolloutRestApi.class).getRollout(rollout.getId())).withSelfRel().expand()); return body; } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java index dcae6b389..7b1903430 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleMapper.java @@ -112,23 +112,23 @@ public final class MgmtSoftwareModuleMapper { response.setEncrypted(softwareModule.isEncrypted()); response.add(linkTo(methodOn(MgmtSoftwareModuleRestApi.class).getSoftwareModule(response.getModuleId())) - .withSelfRel()); + .withSelfRel().expand()); return response; } static void addLinks(final SoftwareModule softwareModule, final MgmtSoftwareModule response) { response.add(linkTo(methodOn(MgmtSoftwareModuleRestApi.class).getArtifacts(response.getModuleId())) - .withRel(MgmtRestConstants.SOFTWAREMODULE_V1_ARTIFACT)); + .withRel(MgmtRestConstants.SOFTWAREMODULE_V1_ARTIFACT).expand()); response.add(linkTo( methodOn(MgmtSoftwareModuleTypeRestApi.class).getSoftwareModuleType(softwareModule.getType().getId())) - .withRel(MgmtRestConstants.SOFTWAREMODULE_V1_TYPE)); + .withRel(MgmtRestConstants.SOFTWAREMODULE_V1_TYPE).expand()); response.add(linkTo(methodOn(MgmtSoftwareModuleResource.class).getMetadata(response.getModuleId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata") - .expand()); + .expand().expand()); } static MgmtArtifact toResponse(final Artifact artifact) { @@ -143,7 +143,7 @@ public final class MgmtSoftwareModuleMapper { MgmtRestModelMapper.mapBaseToBase(artifactRest, artifact); artifactRest.add(linkTo(methodOn(MgmtSoftwareModuleRestApi.class) - .getArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withSelfRel()); + .getArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withSelfRel().expand()); return artifactRest; } @@ -151,7 +151,8 @@ public final class MgmtSoftwareModuleMapper { static void addLinks(final Artifact artifact, final MgmtArtifact response) { response.add(linkTo(methodOn(MgmtDownloadArtifactResource.class) - .downloadArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withRel("download")); + .downloadArtifact(artifact.getSoftwareModule().getId(), artifact.getId())).withRel("download") + .expand()); } static List artifactsToResponse(final Collection artifacts) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java index 61ce58912..36a22122b 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSoftwareModuleTypeMapper.java @@ -72,7 +72,7 @@ final class MgmtSoftwareModuleTypeMapper { result.setColour(type.getColour()); result.add(linkTo(methodOn(MgmtSoftwareModuleTypeRestApi.class).getSoftwareModuleType(result.getModuleId())) - .withSelfRel()); + .withSelfRel().expand()); return result; } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java index a6348973b..da15885d4 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTagMapper.java @@ -60,7 +60,8 @@ final class MgmtTagMapper { mapTag(response, targetTag); - response.add(linkTo(methodOn(MgmtTargetTagRestApi.class).getTargetTag(targetTag.getId())).withSelfRel()); + response.add( + linkTo(methodOn(MgmtTargetTagRestApi.class).getTargetTag(targetTag.getId())).withSelfRel().expand()); return response; } @@ -68,8 +69,8 @@ final class MgmtTagMapper { static void addLinks(final TargetTag targetTag, final MgmtTag response) { response.add(linkTo(methodOn(MgmtTargetTagRestApi.class).getAssignedTargets(targetTag.getId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, - MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)) - .withRel("assignedTargets")); + MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("assignedTargets") + .expand()); } @@ -97,7 +98,7 @@ final class MgmtTagMapper { response.add( linkTo(methodOn(MgmtDistributionSetTagRestApi.class).getDistributionSetTag(distributionSetTag.getId())) - .withSelfRel()); + .withSelfRel().expand()); return response; } @@ -106,7 +107,7 @@ final class MgmtTagMapper { response.add(linkTo(methodOn(MgmtDistributionSetTagRestApi.class).getAssignedDistributionSets( distributionSetTag.getId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)) - .withRel("assignedDistributionSets")); + .withRel("assignedDistributionSets").expand()); } static List mapTagFromRequest(final EntityFactory entityFactory, diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java index d7ebd4203..05add94ae 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryMapper.java @@ -68,14 +68,15 @@ public final class MgmtTargetFilterQueryMapper { } } - targetRest.add(linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withSelfRel()); + targetRest.add( + linkTo(methodOn(MgmtTargetFilterQueryRestApi.class).getFilter(filter.getId())).withSelfRel().expand()); return targetRest; } static void addLinks(final MgmtTargetFilterQuery targetRest) { targetRest.add(linkTo(methodOn(MgmtTargetFilterQueryRestApi.class) - .postAssignedDistributionSet(targetRest.getFilterId(), null)).withRel("autoAssignDS")); + .postAssignedDistributionSet(targetRest.getFilterId(), null)).withRel("autoAssignDS").expand()); } static TargetFilterQueryCreate fromRequest(final EntityFactory entityFactory, diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java index 6d3094c37..36282ac88 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetMapper.java @@ -72,25 +72,26 @@ public final class MgmtTargetMapper { */ public static void addTargetLinks(final MgmtTarget response) { response.add(linkTo(methodOn(MgmtTargetRestApi.class).getAssignedDistributionSet(response.getControllerId())) - .withRel(MgmtRestConstants.TARGET_V1_ASSIGNED_DISTRIBUTION_SET)); + .withRel(MgmtRestConstants.TARGET_V1_ASSIGNED_DISTRIBUTION_SET).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getInstalledDistributionSet(response.getControllerId())) - .withRel(MgmtRestConstants.TARGET_V1_INSTALLED_DISTRIBUTION_SET)); + .withRel(MgmtRestConstants.TARGET_V1_INSTALLED_DISTRIBUTION_SET).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getAttributes(response.getControllerId())) - .withRel(MgmtRestConstants.TARGET_V1_ATTRIBUTES)); + .withRel(MgmtRestConstants.TARGET_V1_ATTRIBUTES).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionHistory(response.getControllerId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionFields.ID.getFieldName() + ":" + SortDirection.DESC, null)) .withRel(MgmtRestConstants.TARGET_V1_ACTIONS).expand()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).getMetadata(response.getControllerId(), MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET_VALUE, - MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata")); + MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, null, null)).withRel("metadata") + .expand()); if (response.getTargetType() != null) { response.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getTargetType(response.getTargetType())) - .withRel(MgmtRestConstants.TARGET_V1_ASSIGNED_TARGET_TYPE)); + .withRel(MgmtRestConstants.TARGET_V1_ASSIGNED_TARGET_TYPE).expand()); } if (response.getAutoConfirmActive() != null) { response.add(linkTo(methodOn(MgmtTargetRestApi.class).getAutoConfirmStatus(response.getControllerId())) - .withRel(MgmtRestConstants.TARGET_V1_AUTO_CONFIRM)); + .withRel(MgmtRestConstants.TARGET_V1_AUTO_CONFIRM).expand()); } } @@ -102,11 +103,11 @@ public final class MgmtTargetMapper { response.setInitiator(status.getInitiator()); response.setRemark(status.getRemark()); response.add(linkTo(methodOn(MgmtTargetRestApi.class).deactivateAutoConfirm(target.getControllerId())) - .withRel(MgmtRestConstants.TARGET_V1_DEACTIVATE_AUTO_CONFIRM)); + .withRel(MgmtRestConstants.TARGET_V1_DEACTIVATE_AUTO_CONFIRM).expand()); } else { response = MgmtTargetAutoConfirm.disabled(); response.add(linkTo(methodOn(MgmtTargetRestApi.class).activateAutoConfirm(target.getControllerId(), null)) - .withRel(MgmtRestConstants.TARGET_V1_ACTIVATE_AUTO_CONFIRM)); + .withRel(MgmtRestConstants.TARGET_V1_ACTIVATE_AUTO_CONFIRM).expand()); } return response; } @@ -192,7 +193,8 @@ public final class MgmtTargetMapper { targetRest.setAutoConfirmActive(target.getAutoConfirmationStatus() != null); } - targetRest.add(linkTo(methodOn(MgmtTargetRestApi.class).getTarget(target.getControllerId())).withSelfRel()); + targetRest.add( + linkTo(methodOn(MgmtTargetRestApi.class).getTarget(target.getControllerId())).withSelfRel().expand()); return targetRest; } @@ -260,7 +262,7 @@ public final class MgmtTargetMapper { action.getLastActionStatusCode().ifPresent(statusCode -> { result.setLastStatusCode(statusCode); }); - + final Rollout rollout = action.getRollout(); if (rollout != null) { result.setRollout(rollout.getId()); @@ -279,7 +281,8 @@ public final class MgmtTargetMapper { MgmtRestModelMapper.mapBaseToBase(result, action); - result.add(linkTo(methodOn(MgmtTargetRestApi.class).getAction(targetId, action.getId())).withSelfRel()); + result.add( + linkTo(methodOn(MgmtTargetRestApi.class).getAction(targetId, action.getId())).withSelfRel().expand()); return result; } @@ -289,25 +292,26 @@ public final class MgmtTargetMapper { if (action.isCancelingOrCanceled()) { result.add(linkTo(methodOn(MgmtTargetRestApi.class).getAction(controllerId, action.getId())) - .withRel(MgmtRestConstants.TARGET_V1_CANCELED_ACTION)); + .withRel(MgmtRestConstants.TARGET_V1_CANCELED_ACTION).expand()); } result.add(linkTo(methodOn(MgmtTargetRestApi.class).getTarget(controllerId)).withRel("target") - .withName(action.getTarget().getName())); + .withName(action.getTarget().getName()).expand()); final DistributionSet distributionSet = action.getDistributionSet(); result.add(linkTo(methodOn(MgmtDistributionSetRestApi.class).getDistributionSet(distributionSet.getId())) - .withRel("distributionset").withName(distributionSet.getName() + ":" + distributionSet.getVersion())); + .withRel("distributionset").withName(distributionSet.getName() + ":" + distributionSet.getVersion()) + .expand()); result.add(linkTo(methodOn(MgmtTargetRestApi.class).getActionStatusList(controllerId, action.getId(), 0, MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_LIMIT_VALUE, ActionStatusFields.ID.getFieldName() + ":" + SortDirection.DESC)) - .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS)); + .withRel(MgmtRestConstants.TARGET_V1_ACTION_STATUS).expand()); final Rollout rollout = action.getRollout(); if (rollout != null) { result.add(linkTo(methodOn(MgmtRolloutRestApi.class).getRollout(rollout.getId())) - .withRel(MgmtRestConstants.TARGET_V1_ROLLOUT).withName(rollout.getName())); + .withRel(MgmtRestConstants.TARGET_V1_ROLLOUT).withName(rollout.getName()).expand()); } return result; diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java index ab5dda58e..26baf1f39 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTypeMapper.java @@ -8,6 +8,9 @@ */ package org.eclipse.hawkbit.mgmt.rest.resource; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; +import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; + import java.util.Collection; import java.util.Collections; import java.util.List; @@ -24,9 +27,6 @@ import org.eclipse.hawkbit.repository.builder.TargetTypeCreate; import org.eclipse.hawkbit.repository.model.TargetType; import org.eclipse.hawkbit.rest.data.ResponseList; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.linkTo; -import static org.springframework.hateoas.server.mvc.WebMvcLinkBuilder.methodOn; - /** * A mapper which maps repository model to RESTful model representation and * back. @@ -43,13 +43,15 @@ public final class MgmtTargetTypeMapper { if (targetTypesRest == null) { return Collections.emptyList(); } - return targetTypesRest.stream().map(targetRest -> fromRequest(entityFactory, targetRest)).collect(Collectors.toList()); + return targetTypesRest.stream().map(targetRest -> fromRequest(entityFactory, targetRest)) + .collect(Collectors.toList()); } private static TargetTypeCreate fromRequest(final EntityFactory entityFactory, final MgmtTargetTypeRequestBodyPost targetTypesRest) { - return entityFactory.targetType().create().name(targetTypesRest.getName()).description(targetTypesRest.getDescription()) - .colour(targetTypesRest.getColour()).compatible(getDistributionSets(targetTypesRest)); + return entityFactory.targetType().create().name(targetTypesRest.getName()) + .description(targetTypesRest.getDescription()).colour(targetTypesRest.getColour()) + .compatible(getDistributionSets(targetTypesRest)); } private static Collection getDistributionSets(final MgmtTargetTypeRequestBodyPost targetTypesRest) { @@ -70,12 +72,13 @@ public final class MgmtTargetTypeMapper { MgmtRestModelMapper.mapNamedToNamed(result, type); result.setTypeId(type.getId()); result.setColour(type.getColour()); - result.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getTargetType(result.getTypeId())).withSelfRel()); + result.add( + linkTo(methodOn(MgmtTargetTypeRestApi.class).getTargetType(result.getTypeId())).withSelfRel().expand()); return result; } static void addLinks(final MgmtTargetType result) { result.add(linkTo(methodOn(MgmtTargetTypeRestApi.class).getCompatibleDistributionSets(result.getTypeId())) - .withRel(MgmtRestConstants.TARGETTYPE_V1_DS_TYPES)); + .withRel(MgmtRestConstants.TARGETTYPE_V1_DS_TYPES).expand()); } } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java index f93cf0b8d..fc9cbf356 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementMapper.java @@ -50,8 +50,8 @@ public final class MgmtTenantManagementMapper { restConfValue.setLastModifiedAt(repoConfValue.getLastModifiedAt()); restConfValue.setLastModifiedBy(repoConfValue.getLastModifiedBy()); - restConfValue.add( - linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(key)).withSelfRel()); + restConfValue.add(linkTo(methodOn(MgmtTenantManagementResource.class).getTenantConfigurationValue(key)) + .withSelfRel().expand()); return restConfValue; } diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java index 7aa28db41..dff042c6b 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetTagResourceTest.java @@ -86,7 +86,7 @@ public class MgmtDistributionSetTagResourceTest extends AbstractManagementApiInt .andExpect(applyTagMatcherOnSingleResult(assigned)) .andExpect(applySelfLinkMatcherOnSingleResult(DISTRIBUTIONSETTAGS_ROOT + assigned.getId())) .andExpect(jsonPath("_links.assignedDistributionSets.href", - equalTo(DISTRIBUTIONSETTAGS_ROOT + assigned.getId() + "/assigned?offset=0&limit=50{&sort,q}"))); + equalTo(DISTRIBUTIONSETTAGS_ROOT + assigned.getId() + "/assigned?offset=0&limit=50"))); } @Test diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index 4ae815cd2..8fc570de6 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -588,7 +588,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { .andExpect(jsonPath("$._links.assignedDS.href", equalTo(hrefPrefix + "assignedDS"))) .andExpect(jsonPath("$._links.installedDS.href", equalTo(hrefPrefix + "installedDS"))) .andExpect(jsonPath("$._links.actions.href", - equalTo(hrefPrefix + "actions" + "?offset=0&limit=50&sort=id:DESC"))); + equalTo(hrefPrefix + "actions" + "?offset=0&limit=50&sort=id%3ADESC"))); } @Test @@ -1242,7 +1242,7 @@ class MgmtTargetResourceTest extends AbstractManagementApiIntegrationTest { private String generateStatusreferenceLink(final String knownTargetId, final Long actionId) { return "http://localhost" + MgmtRestConstants.TARGET_V1_REQUEST_MAPPING + "/" + knownTargetId + "/" + MgmtRestConstants.TARGET_V1_ACTIONS + "/" + actionId + "/" + MgmtRestConstants.TARGET_V1_ACTION_STATUS - + "?offset=0&limit=50&sort=id:DESC"; + + "?offset=0&limit=50&sort=id%3ADESC"; } private List generateTargetWithTwoUpdatesWithOneOverride(final String knownTargetId) { diff --git a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java index 7f85ce16c..6369d698d 100644 --- a/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java +++ b/hawkbit-rest/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetTagResourceTest.java @@ -88,7 +88,7 @@ public class MgmtTargetTagResourceTest extends AbstractManagementApiIntegrationT .andExpect(applyTagMatcherOnSingleResult(assigned)) .andExpect(applySelfLinkMatcherOnSingleResult(TARGETTAGS_ROOT + assigned.getId())) .andExpect(jsonPath("_links.assignedTargets.href", - equalTo(TARGETTAGS_ROOT + assigned.getId() + "/assigned?offset=0&limit=50{&sort,q}"))); + equalTo(TARGETTAGS_ROOT + assigned.getId() + "/assigned?offset=0&limit=50"))); } diff --git a/hawkbit-rest/hawkbit-rest-core/pom.xml b/hawkbit-rest/hawkbit-rest-core/pom.xml index 9d5e3035e..ae0af2623 100644 --- a/hawkbit-rest/hawkbit-rest-core/pom.xml +++ b/hawkbit-rest/hawkbit-rest-core/pom.xml @@ -35,8 +35,8 @@ commons-lang3 - org.springframework - spring-web + org.springframework.boot + spring-boot-starter-web org.springframework.hateoas diff --git a/hawkbit-runtime/docker/README.md b/hawkbit-runtime/docker/README.md index 9c14f3e07..3f18ab2e6 100644 --- a/hawkbit-runtime/docker/README.md +++ b/hawkbit-runtime/docker/README.md @@ -47,7 +47,7 @@ hawkbit: image: "hawkbit/hawkbit-update-server:latest-mysql" environment: SPRING_APPLICATION_JSON: '{ - "spring.datasource.url": "jdbc:mysql://mysql:3306/hawkbit", + "spring.datasource.url": "jdbc:mariadb://mysql:3306/hawkbit", "spring.rabbitmq.host": "rabbitmq", "spring.rabbitmq.username": "guest", "spring.rabbitmq.password": "guest", diff --git a/hawkbit-runtime/docker/docker-compose.yml b/hawkbit-runtime/docker/docker-compose.yml index 9b9e6bb64..b7b99e5c9 100644 --- a/hawkbit-runtime/docker/docker-compose.yml +++ b/hawkbit-runtime/docker/docker-compose.yml @@ -45,7 +45,7 @@ services: hawkbit: image: "hawkbit/hawkbit-update-server:latest-mysql" environment: - - 'SPRING_DATASOURCE_URL=jdbc:mysql://mysql:3306/hawkbit' + - 'SPRING_DATASOURCE_URL=jdbc:mariadb://mysql:3306/hawkbit' - 'SPRING_RABBITMQ_HOST=rabbitmq' - 'SPRING_RABBITMQ_USERNAME=guest' - 'SPRING_RABBITMQ_PASSWORD=guest' diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/ErrorController.java b/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/ErrorController.java index da4c46be2..9509bd8de 100644 --- a/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/ErrorController.java +++ b/hawkbit-runtime/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/ErrorController.java @@ -60,7 +60,7 @@ public class ErrorController extends BasicErrorController { } private Map getErrorAttributesWithoutPath(final HttpServletRequest request) { - final Map body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.ALL)); + final Map body = getErrorAttributes(request, getErrorAttributeOptions(request, MediaType.ALL)); if (body != null && body.containsKey(PATH)) { body.remove(PATH); } diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/resources/application-mysql.properties b/hawkbit-runtime/hawkbit-update-server/src/main/resources/application-mysql.properties index 28aa0b3e9..e49989df3 100644 --- a/hawkbit-runtime/hawkbit-update-server/src/main/resources/application-mysql.properties +++ b/hawkbit-runtime/hawkbit-update-server/src/main/resources/application-mysql.properties @@ -12,7 +12,7 @@ # see https://www.eclipse.org/hawkbit/guides/runhawkbit/ spring.jpa.database=MYSQL -spring.datasource.url=jdbc:mysql://localhost:3306/hawkbit +spring.datasource.url=jdbc:mariadb://localhost:3306/hawkbit spring.datasource.username=root spring.datasource.password= spring.datasource.driverClassName=org.mariadb.jdbc.Driver diff --git a/pom.xml b/pom.xml index a2c7e47b2..592470086 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ org.springframework.boot spring-boot-starter-parent - 2.3.12.RELEASE + 2.7.10 org.eclipse.hawkbit @@ -130,9 +130,9 @@ 11 - 2.3.12.RELEASE - 5.2.22.RELEASE - Hoxton.SR12 + 2.7.10 + 5.3.26 + 2021.0.5 2.0.0.RELEASE true @@ -141,17 +141,28 @@ upgrade) - START --> - 3.5.0.RELEASE + + 1.33 + + 2.7.8 + + 2.14.2 + + 5.7.7 + + 3.12.1 + - 8.14.1 + + 8.14.3 3.2.1 2.0.0.RELEASE ${vaadin.version} 3.0.1 1.3.0 - 2.8.2 + 2.9.0 @@ -171,10 +182,10 @@ 9.1.6 1.15.3 - 2.13.6 + 2.13.10 2.7.11 2.7.9.1 - 2.3.0 + 2.3.1 1.1.8 30.1.1-jre 2.2.4 @@ -187,8 +198,6 @@ 1.2.9 - - 2.14.0 @@ -758,14 +767,6 @@ org.springframework.boot spring-boot-starter-test ${spring.boot.version} - - - - - org.junit.vintage - junit-vintage-engine - - org.eclipse.persistence @@ -777,6 +778,11 @@ spring-plugin-core ${spring.plugin.core.version} + + org.springframework.security + spring-security-oauth2-client + ${spring-security-oauth2-client.version} +