diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 075f30ba0..b8b5011aa 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -62,8 +62,9 @@ public class DeviceSimulatorUpdater { device.setProgress(0.0); device.setSwversion(swVersion); eventbus.post(new InitUpdate(device)); + threadPool.schedule(new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback), - 2000, TimeUnit.MILLISECONDS); + 2_000, TimeUnit.MILLISECONDS); } private static final class DeviceSimulatorUpdateThread implements Runnable { @@ -91,7 +92,7 @@ public class DeviceSimulatorUpdater { if (newProgress < 1.0) { threadPool.schedule( new DeviceSimulatorUpdateThread(device, spSenderService, actionId, eventbus, callback), - rndSleep.nextInt(3000), TimeUnit.MILLISECONDS); + rndSleep.nextInt(5_000), TimeUnit.MILLISECONDS); } else { callback.updateFinished(device, actionId); } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java index 6f0ac732e..1c314d56f 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java @@ -13,11 +13,8 @@ import java.util.Map; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey; import org.eclipse.hawkbit.dmf.amqp.api.MessageType; -import org.eclipse.hawkbit.dmf.json.model.ActionStatus; import org.eclipse.hawkbit.dmf.json.model.DownloadAndUpdateRequest; -import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice; import org.eclipse.hawkbit.simulator.DeviceSimulatorUpdater; -import org.eclipse.hawkbit.simulator.DeviceSimulatorUpdater.UpdaterCallback; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.amqp.core.Message; @@ -139,31 +136,22 @@ public class SpReceiverService extends ReceiverService { DownloadAndUpdateRequest.class); final Long actionId = downloadAndUpdateRequest.getActionId(); - try { - Thread.sleep(1_000); - } catch (final InterruptedException e) { - LOGGER.error("Sleep interrupted", e); - } - - spSenderService.sendActionStatusMessage(tenant, ActionStatus.RUNNING, - "device Simulator retrieved update request. proceeding with simulation.", actionId); - deviceUpdater.startUpdate(tenant, thingId, actionId, downloadAndUpdateRequest.getSoftwareModules().get(0) - .getModuleVersion(), new UpdaterCallback() { - @Override - public void updateFinished(final AbstractSimulatedDevice device, final Long actionId) { - switch (device.getResponseStatus()) { - case SUCCESSFUL: - spSenderService.finishUpdateProcess(new SimulatedUpdate(device.getTenant(), device.getId(), - actionId), "Simulation complete!"); - break; - case ERROR: - spSenderService.finishUpdateProcessWithError(new SimulatedUpdate(device.getTenant(), - device.getId(), actionId), "Simulation complete with error!"); - break; - default: - break; - } - } - }); + deviceUpdater.startUpdate(tenant, thingId, actionId, + downloadAndUpdateRequest.getSoftwareModules().get(0).getModuleVersion(), (device, actionId1) -> { + switch (device.getResponseStatus()) { + case SUCCESSFUL: + spSenderService.finishUpdateProcess( + new SimulatedUpdate(device.getTenant(), device.getId(), actionId1), + "Simulation complete!"); + break; + case ERROR: + spSenderService.finishUpdateProcessWithError( + new SimulatedUpdate(device.getTenant(), device.getId(), actionId1), + "Simulation complete with error!"); + break; + default: + break; + } + }); } } diff --git a/examples/hawkbit-example-app/src/main/resources/application.properties b/examples/hawkbit-example-app/src/main/resources/application.properties index d3eddeff1..7864087c8 100644 --- a/examples/hawkbit-example-app/src/main/resources/application.properties +++ b/examples/hawkbit-example-app/src/main/resources/application.properties @@ -24,3 +24,18 @@ spring.rabbitmq.port=5672 hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver + +# UI demo account +hawkbit.server.ui.demo.password=admin +hawkbit.server.ui.demo.user=admin +hawkbit.server.ui.demo.tenant=DEFAULT + +# UI help links +hawkbit.server.ui.links.documentation.root=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.deployment-view=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.distribution-view=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.rollout-view=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.security=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.system-configuration-view=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.targetfilter-view=https://github.com/eclipse/hawkbit +hawkbit.server.ui.links.documentation.upload-view=https://github.com/eclipse/hawkbit diff --git a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties index 5e767726a..dcb3e8fb4 100644 --- a/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties +++ b/hawkbit-autoconfigure/src/main/resources/hawkbitdefaults.properties @@ -37,7 +37,7 @@ hawkbit.threadpool.queuesize=20000 hawkbit.controller.pollingTime=00:05:00 hawkbit.controller.pollingOverdueTime=00:05:00 -## Configuration for RabbitMQ integration +# Configuration for RabbitMQ integration hawkbit.dmf.rabbitmq.deadLetterQueue=dmf_connector_deadletter hawkbit.dmf.rabbitmq.deadLetterExchange=dmf.connector.deadletter -hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver +hawkbit.dmf.rabbitmq.receiverQueue=dmf_receiver \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java index eef36f552..fb9166529 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/FieldNameProvider.java @@ -20,7 +20,7 @@ import java.util.Map; */ public interface FieldNameProvider { /** - * Seperator for the sub attributes + * Separator for the sub attributes */ public static final String SUB_ATTRIBUTE_SEPERATOR = "."; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java index beb46a9d7..68e4f4427 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/SoftwareModuleTypeFields.java @@ -36,7 +36,7 @@ public enum SoftwareModuleTypeFields implements FieldNameProvider { /** * The max ds assignments field. */ - MAX("maxAssignments"); + MAXASSIGNMENTS("maxAssignments"); private final String fieldName; diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index e1976c9a6..aad0839cd 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -572,7 +572,7 @@ public class DeploymentManagement { @Modifying @Transactional @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_TARGET) - public Action forceQuitAction(@NotNull final Action action, @NotNull final Target target) { + public Action forceQuitAction(@NotNull final Action action) { final Action mergedAction = entityManager.merge(action); if (!mergedAction.isCancelingOrCanceled()) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java index bb7781733..07a97ebcf 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java @@ -69,7 +69,7 @@ import org.springframework.data.domain.Persistable; @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "controller_id", "tenant" }, name = "uk_tenant_controller_id") ) + "controller_id", "tenant" }, name = "uk_tenant_controller_id")) @NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) public class Target extends NamedEntity implements Persistable { @@ -81,21 +81,21 @@ public class Target extends NamedEntity implements Persistable { private String controllerId; @Transient - private boolean isNew = false; + private boolean entityNew = false; @ManyToMany(targetEntity = TargetTag.class) @JoinTable(name = "sp_target_target_tag", joinColumns = { - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target") ) }, inverseJoinColumns = { - @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag") ) }) + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { + @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) private Set tags = new HashSet<>(); @CascadeOnDelete @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { CascadeType.REMOVE }) - @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ") ) + @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) private final List actions = new ArrayList<>(); @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = DistributionSet.class) - @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds") ) + @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) private DistributionSet assignedDistributionSet; @CascadeOnDelete @@ -217,15 +217,15 @@ public class Target extends NamedEntity implements Persistable { @Override @Transient public boolean isNew() { - return isNew; + return entityNew; } /** * @param isNew * the isNew to set */ - public void setNew(final boolean isNew) { - this.isNew = isNew; + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; } /** diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java index d491319fa..e487ee85a 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/TargetInfo.java @@ -73,11 +73,11 @@ public class TargetInfo implements Persistable, Serializable { private Long targetId; @Transient - private boolean isNew = false; + private boolean entityNew = false; @CascadeOnDelete @OneToOne(cascade = { CascadeType.MERGE, CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = Target.class) - @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ") ) + @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) @MapsId // use deprecated annotation until HHH-8862 is fixed // @SuppressWarnings( "deprecation" ) @@ -98,7 +98,7 @@ public class TargetInfo implements Persistable, Serializable { private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; @ManyToOne(optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds") ) + @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) private DistributionSet installedDistributionSet; /** @@ -108,7 +108,7 @@ public class TargetInfo implements Persistable, Serializable { @Column(name = "attribute_value", length = 128) @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) @CollectionTable(name = "sp_target_attributes", joinColumns = { - @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target") ) + @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) // use deprecated annotation until HHH-8862 is fixed @SuppressWarnings("deprecation") // @org.hibernate.annotations.ForeignKey( name = "fk_targ_attrib_target" ) @@ -154,15 +154,15 @@ public class TargetInfo implements Persistable, Serializable { @Override @Transient public boolean isNew() { - return isNew; + return entityNew; } /** * @param isNew * the isNew to set */ - public void setNew(final boolean isNew) { - this.isNew = isNew; + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; } /** diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java index 9d5fa2483..18f9bca06 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/AbstractIntegrationTest.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit; import static org.fest.assertions.api.Assertions.assertThat; import java.util.List; -import java.util.Properties; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -31,6 +30,7 @@ import org.eclipse.hawkbit.repository.LocalArtifactRepository; import org.eclipse.hawkbit.repository.RolloutGroupManagement; import org.eclipse.hawkbit.repository.RolloutGroupRepository; import org.eclipse.hawkbit.repository.RolloutManagement; +import org.eclipse.hawkbit.repository.RolloutRepository; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SoftwareModuleMetadataRepository; import org.eclipse.hawkbit.repository.SoftwareModuleRepository; @@ -190,6 +190,9 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @Autowired protected RolloutGroupRepository rolloutGroupRepository; + @Autowired + protected RolloutRepository rolloutRepository; + protected MockMvc mvc; @Autowired @@ -208,23 +211,6 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { private static CIMySqlTestDatabase tesdatabase; - static { - final Properties props = System.getProperties(); - - // if( props.getProperty( SuiteEmbeddedConfiguration.IM_HOME ) == null ) - // { - // props.setProperty( SuiteEmbeddedConfiguration.IM_HOME, - // "./src/test/resources/im" ); - // } - - } - - /* - * (non-Javadoc) - * - * @see org.springframework.context.EnvironmentAware#setEnvironment(org. - * springframework.core.env. Environment) - */ @Override public void setEnvironment(final Environment environment) { this.environment = environment; @@ -287,6 +273,8 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { assertThat(softwareModuleTypeRepository.findAll()).isEmpty(); assertThat(distributionSetTypeRepository.findAll()).isEmpty(); assertThat(tenantMetaDataRepository.findAll()).isEmpty(); + assertThat(rolloutGroupRepository.findAll()).isEmpty(); + assertThat(rolloutRepository.findAll()).isEmpty(); } @Transactional diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java index 9530a61c3..ecf079c29 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/DeploymentManagementTest.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import java.util.ArrayList; @@ -312,7 +311,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { deploymentManagement.cancelAction(assigningAction, target); assigningAction = deploymentManagement.findActionWithDetails(assigningAction.getId()); - deploymentManagement.forceQuitAction(assigningAction, target); + deploymentManagement.forceQuitAction(assigningAction); assigningAction = deploymentManagement.findActionWithDetails(assigningAction.getId()); @@ -350,8 +349,7 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { // force quit assignment try { - deploymentManagement.forceQuitAction(assigningAction, - targetManagement.findTargetByControllerID(target.getControllerId())); + deploymentManagement.forceQuitAction(assigningAction); fail("expected ForceQuitActionNotAllowedException"); } catch (final ForceQuitActionNotAllowedException ex) { } @@ -764,13 +762,16 @@ public class DeploymentManagementTest extends AbstractIntegrationTest { distributionSetManagement.findDistributionSetByIdWithDetails(dsA.getId()).getOptLockRevision()); // verifying that the assignment is correct - assertEquals("Active target actions are wrong", 1, deploymentManagement.findActiveActionsByTarget(targ).size()); - assertEquals("Target actions are wrong", 1, deploymentManagement.findActionsByTarget(targ).size()); - assertEquals("Target status is wrong", TargetUpdateStatus.PENDING, targ.getTargetInfo().getUpdateStatus()); - assertEquals("Assigned ds is wrong", dsA, targ.getAssignedDistributionSet()); - assertEquals("Active ds is wrong", dsA, - deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()); - assertNull("Installed ds should be null", targ.getTargetInfo().getInstalledDistributionSet()); + assertThat(deploymentManagement.findActiveActionsByTarget(targ).size()).as("Active target actions are wrong") + .isEqualTo(1); + assertThat(deploymentManagement.findActionsByTarget(targ).size()).as("Target actions are wrong").isEqualTo(1); + assertThat(targ.getTargetInfo().getUpdateStatus()).as("UpdateStatus of target is wrong") + .isEqualTo(TargetUpdateStatus.PENDING); + assertThat(targ.getAssignedDistributionSet()).as("Assigned distribution set of target is wrong").isEqualTo(dsA); + assertThat(deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()) + .as("Distribution set of actionn is wrong").isEqualTo(dsA); + assertThat(deploymentManagement.findActiveActionsByTarget(targ).get(0).getDistributionSet()) + .as("Installed distribution set of action should be null").isNotNull(); final Page updAct = actionRepository.findByDistributionSet(pageReq, dsA); final Action action = updAct.getContent().get(0); diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java index a405e7b7d..22f9ee8b4 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/RolloutManagementTest.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; import org.eclipse.hawkbit.AbstractIntegrationTest; import org.eclipse.hawkbit.TestDataUtil; @@ -34,6 +35,8 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; import org.eclipse.hawkbit.repository.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.utils.MultipleInvokeHelper; +import org.eclipse.hawkbit.repository.utils.SuccessCondition; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Description; @@ -859,7 +862,7 @@ public class RolloutManagementTest extends AbstractIntegrationTest { @Test @Description("Verify the creation and the start of a rollout in asynchronous mode.") - public void createAndStartRolloutInAsync() { + public void createAndStartRolloutInAsync() throws Exception { final int amountTargetsForRollout = 500; final int amountGroups = 5; @@ -883,31 +886,18 @@ public class RolloutManagementTest extends AbstractIntegrationTest { myRollout = rolloutManagement.createRolloutAsync(myRollout, amountGroups, conditions); - int counter = 1; - int counterMax = 10; - while (!isRolloutInGivenStatus(myRollout.getId(), RolloutStatus.READY) && (counter <= counterMax)) { - try { - Thread.sleep(500); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - counter++; - } + SuccessConditionRolloutStatus conditionRolloutTargetCount = new SuccessConditionRolloutStatus( + RolloutStatus.READY); + assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()), + conditionRolloutTargetCount, 15000, 500)).as("Rollout status").isNotNull(); myRollout = rolloutManagement.findRolloutById(myRollout.getId()); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); rolloutManagement.startRolloutAsync(myRollout); - counter = 1; - counterMax = 10; - while (!isRolloutInGivenStatus(myRollout.getId(), RolloutStatus.RUNNING) && counter <= counterMax) { - try { - Thread.sleep(500); - } catch (final InterruptedException e) { - e.printStackTrace(); - } - counter++; - } + conditionRolloutTargetCount = new SuccessConditionRolloutStatus(RolloutStatus.RUNNING); + assertThat(MultipleInvokeHelper.doWithTimeout(new RolloutStatusCallable(myRollout.getId()), + conditionRolloutTargetCount, 15000, 500)).as("Rollout status").isNotNull(); myRollout = rolloutManagement.findRolloutById(myRollout.getId()); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.RUNNING); @@ -917,14 +907,6 @@ public class RolloutManagementTest extends AbstractIntegrationTest { validateRolloutActionStatus(myRollout.getId(), expectedTargetCountStatus); } - private boolean isRolloutInGivenStatus(final Long rolloutID, final RolloutStatus status) { - final Rollout myRollout = rolloutManagement.findRolloutById(rolloutID); - if (myRollout.getStatus() == status) { - return true; - } - return false; - } - private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup, final Map expectedTargetCountStatus) { final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement @@ -1021,4 +1003,35 @@ public class RolloutManagementTest extends AbstractIntegrationTest { return map; } + private static class SuccessConditionRolloutStatus implements SuccessCondition { + + private final RolloutStatus rolloutStatus; + + public SuccessConditionRolloutStatus(final RolloutStatus rolloutStatus) { + this.rolloutStatus = rolloutStatus; + } + + @Override + public boolean success(final RolloutStatus result) { + return result.equals(rolloutStatus); + } + } + + private class RolloutStatusCallable implements Callable { + + final Long rolloutId; + + RolloutStatusCallable(final Long rolloutId) { + this.rolloutId = rolloutId; + } + + @Override + public RolloutStatus call() throws Exception { + + final Rollout myRollout = rolloutManagement.findRolloutById(rolloutId); + return myRollout.getStatus(); + + } + } + } diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java index 12f4005ac..268bddf50 100644 --- a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/rsql/RSQLSoftwareModuleTypeFieldsTest.java @@ -55,7 +55,7 @@ public class RSQLSoftwareModuleTypeFieldsTest extends AbstractIntegrationTest { @Test @Description("Test filter software module test type by max") public void testFilterByMaxAssignment() { - assertRSQLQuery(SoftwareModuleTypeFields.MAX.name() + "==1", 3); + assertRSQLQuery(SoftwareModuleTypeFields.MAXASSIGNMENTS.name() + "==1", 3); } private void assertRSQLQuery(final String rsqlParam, final long excpectedEntity) { diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/MultipleInvokeHelper.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/MultipleInvokeHelper.java new file mode 100644 index 000000000..d40fe1fd0 --- /dev/null +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/MultipleInvokeHelper.java @@ -0,0 +1,94 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.utils; + +import java.util.concurrent.Callable; + +/** + * Helper to call a request multiple times regarding a given condition until + * timeout is reached. + * + */ +public final class MultipleInvokeHelper { + + /** + * Call with timeout until result is not null. + * + * @param callable + * class + * @param timeout + * value + * @param pollInterval + * value + * @return + * @throws Exception + */ + public static T doWithTimeoutUntilResultIsNotNull(final Callable callable, final long timeout, + final long pollInterval) throws Exception // NOPMD + { + return doWithTimeout(callable, new SuccessCondition() { + @Override + public boolean success(final T result) { + return result != null; + }; + }, timeout, pollInterval); + } + + /** + * Call with timeout. + * + * @param callable + * class + * @param successCondition + * class + * @param timeout + * value + * @param pollInterval + * value + * @return + * @throws Exception + */ + public static T doWithTimeout(final Callable callable, final SuccessCondition successCondition, + final long timeout, final long pollInterval) throws Exception // NOPMD + { + + if (pollInterval < 0) { + throw new IllegalArgumentException("pollInterval must non negative"); + } + + long duration = 0; + Exception exception = null; + T returnValue = null; + while (untilTimeoutReached(timeout, duration)) { + try { + returnValue = callable.call(); + // clear exception + exception = null; + } catch (final Exception ex) { + exception = ex; + } + Thread.sleep(pollInterval); + duration += pollInterval > 0 ? pollInterval : 1; + if (exception == null && successCondition.success(returnValue)) { + return returnValue; + } else { + returnValue = null; + } + } + if (exception != null) { + throw exception; + } + return returnValue; + } + + private static boolean untilTimeoutReached(final long timeout, final long duration) { + return duration <= timeout || timeout < 0; + } + +} diff --git a/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/SuccessCondition.java b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/SuccessCondition.java new file mode 100644 index 000000000..6c9553dc8 --- /dev/null +++ b/hawkbit-repository/src/test/java/org/eclipse/hawkbit/repository/utils/SuccessCondition.java @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2015 Bosch Software Innovations GmbH and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + */ +package org.eclipse.hawkbit.repository.utils; + +/** + * SuccessCondition Interface. + * + * @param + * type of the value to get verified + */ +public interface SuccessCondition { + + /** + * The implementation of the success condition. + * + * @param result + * @return + */ + boolean success(final T result); + +} diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java index 700ef3d96..a5c8544fb 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResource.java @@ -64,7 +64,7 @@ public class DistributionSetTypeResource implements DistributionSetTypeRestApi { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); - final Sort sorting = PagingUtility.sanitizeSoftwareModuleSortParam(sortParam); + final Sort sorting = PagingUtility.sanitizeDistributionSetTypeSortParam(sortParam); final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/PagingUtility.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/PagingUtility.java index 4fb854608..ac45796e5 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/PagingUtility.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/PagingUtility.java @@ -12,10 +12,12 @@ import org.eclipse.hawkbit.repository.ActionFields; import org.eclipse.hawkbit.repository.ActionStatusFields; import org.eclipse.hawkbit.repository.DistributionSetFields; import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; +import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.RolloutFields; import org.eclipse.hawkbit.repository.RolloutGroupFields; import org.eclipse.hawkbit.repository.SoftwareModuleFields; import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; import org.eclipse.hawkbit.repository.TargetFields; import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort.Direction; @@ -48,103 +50,92 @@ public final class PagingUtility { } static Sort sanitizeTargetSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(TargetFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, TargetFields.NAME.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, TargetFields.NAME.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(TargetFields.class, sortParam)); } static Sort sanitizeSoftwareModuleSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(SoftwareModuleFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, SoftwareModuleFields.NAME.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, SoftwareModuleFields.NAME.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(SoftwareModuleFields.class, sortParam)); + } + + static Sort sanitizeSoftwareModuleTypeSortParam(final String sortParam) { + if (sortParam == null) { + // default + return new Sort(Direction.ASC, SoftwareModuleTypeFields.NAME.getFieldName()); + } + return new Sort(SortUtility.parse(SoftwareModuleTypeFields.class, sortParam)); } static Sort sanitizeDistributionSetSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(DistributionSetFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, DistributionSetFields.NAME.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, DistributionSetFields.NAME.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(DistributionSetFields.class, sortParam)); + } + + static Sort sanitizeDistributionSetTypeSortParam(final String sortParam) { + if (sortParam == null) { + // default + return new Sort(Direction.ASC, DistributionSetTypeFields.NAME.getFieldName()); + } + return new Sort(SortUtility.parse(DistributionSetTypeFields.class, sortParam)); } static Sort sanitizeActionSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(ActionFields.class, sortParam)); - } else { + if (sortParam == null) { // default sort is DESC in case of action to match behavior // of management UI (last entry on top) - sorting = new Sort(Direction.DESC, ActionFields.ID.getFieldName()); + return new Sort(Direction.DESC, ActionFields.ID.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(ActionFields.class, sortParam)); } static Sort sanitizeActionStatusSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(ActionStatusFields.class, sortParam)); - } else { + if (sortParam == null) { // default sort is DESC in case of action status to match behavior // of management UI (last entry on top) - sorting = new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName()); + return new Sort(Direction.DESC, ActionStatusFields.ID.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(ActionStatusFields.class, sortParam)); } static Sort sanitizeDistributionSetMetadataSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(DistributionSetMetadataFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, DistributionSetMetadataFields.KEY.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, DistributionSetMetadataFields.KEY.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(DistributionSetMetadataFields.class, sortParam)); } static Sort sanitizeSoftwareModuleMetadataSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(SoftwareModuleMetadataFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, SoftwareModuleMetadataFields.KEY.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, SoftwareModuleMetadataFields.KEY.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(SoftwareModuleMetadataFields.class, sortParam)); } static Sort sanitizeRolloutSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(RolloutFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, RolloutFields.NAME.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, RolloutFields.NAME.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(RolloutFields.class, sortParam)); } static Sort sanitizeRolloutGroupSortParam(final String sortParam) { - final Sort sorting; - if (sortParam != null) { - sorting = new Sort(SortUtility.parse(RolloutGroupFields.class, sortParam)); - } else { - // default sort - sorting = new Sort(Direction.ASC, RolloutGroupFields.NAME.getFieldName()); + if (sortParam == null) { + // default + return new Sort(Direction.ASC, RolloutGroupFields.NAME.getFieldName()); } - return sorting; + return new Sort(SortUtility.parse(RolloutGroupFields.class, sortParam)); } } diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java index c989bf6ad..4259dcc90 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResource.java @@ -48,7 +48,7 @@ public class SoftwareModuleTypeResource implements SoftwareModuleTypeRestApi { final int sanitizedOffsetParam = PagingUtility.sanitizeOffsetParam(pagingOffsetParam); final int sanitizedLimitParam = PagingUtility.sanitizePageLimitParam(pagingLimitParam); - final Sort sorting = PagingUtility.sanitizeSoftwareModuleSortParam(sortParam); + final Sort sorting = PagingUtility.sanitizeSoftwareModuleTypeSortParam(sortParam); final Pageable pageable = new OffsetBasedPageRequest(sanitizedOffsetParam, sanitizedLimitParam, sorting); diff --git a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java index 69a38f87d..faa31a7cc 100644 --- a/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java +++ b/hawkbit-rest-resource/src/main/java/org/eclipse/hawkbit/rest/resource/TargetResource.java @@ -209,7 +209,7 @@ public class TargetResource implements TargetRestApi { final Action action = findActionWithExceptionIfNotFound(actionId); if (force) { - this.deploymentManagement.forceQuitAction(action, target); + this.deploymentManagement.forceQuitAction(action); } else { this.deploymentManagement.cancelAction(action, target); } diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResourceTest.java index 78f4f741e..9f3d2a89d 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/DistributionSetTypeResourceTest.java @@ -89,6 +89,43 @@ public class DistributionSetTypeResourceTest extends AbstractIntegrationTest { .andExpect(jsonPath("$total", equalTo(4))); } + @Test + @WithUser(principal = "uploadTester", allSpPermissions = true) + @Description("Checks the correct behaviour of /rest/v1/distributionsettypes GET requests with sorting by KEY.") + public void getDistributionSetTypesSortedByKey() throws Exception { + + DistributionSetType testType = distributionSetManagement + .createDistributionSetType(new DistributionSetType("zzzzz", "TestName123", "Desc123")); + testType.setDescription("Desc1234"); + testType = distributionSetManagement.updateDistributionSetType(testType); + + // descending + mvc.perform(get("/rest/v1/distributionsettypes").accept(MediaType.APPLICATION_JSON) + .param(RestConstants.REQUEST_PARAMETER_SORTING, "KEY:DESC")).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$content.[0].id", equalTo(testType.getId().intValue()))) + .andExpect(jsonPath("$content.[0].name", equalTo("TestName123"))) + .andExpect(jsonPath("$content.[0].description", equalTo("Desc1234"))) + .andExpect(jsonPath("$content.[0].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[0].createdAt", equalTo(testType.getCreatedAt()))) + .andExpect(jsonPath("$content.[0].lastModifiedBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[0].lastModifiedAt", equalTo(testType.getLastModifiedAt()))) + .andExpect(jsonPath("$content.[0].key", equalTo("zzzzz"))).andExpect(jsonPath("$total", equalTo(4))); + + // ascending + mvc.perform(get("/rest/v1/distributionsettypes").accept(MediaType.APPLICATION_JSON) + .param(RestConstants.REQUEST_PARAMETER_SORTING, "KEY:ASC")).andDo(MockMvcResultPrinter.print()) + .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$content.[3].id", equalTo(testType.getId().intValue()))) + .andExpect(jsonPath("$content.[3].name", equalTo("TestName123"))) + .andExpect(jsonPath("$content.[3].description", equalTo("Desc1234"))) + .andExpect(jsonPath("$content.[3].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[3].createdAt", equalTo(testType.getCreatedAt()))) + .andExpect(jsonPath("$content.[3].lastModifiedBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[3].lastModifiedAt", equalTo(testType.getLastModifiedAt()))) + .andExpect(jsonPath("$content.[3].key", equalTo("zzzzz"))).andExpect(jsonPath("$total", equalTo(4))); + } + @Test @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Checks the correct behaviour of /rest/v1/distributionsettypes POST requests.") diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/RolloutResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/RolloutResourceTest.java index 29cb4ede0..f27eb5186 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/RolloutResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/RolloutResourceTest.java @@ -453,8 +453,8 @@ public class RolloutResourceTest extends AbstractIntegrationTest { .andExpect(status().isOk()); // check if running - assertThat(doWithTimeout(() -> getRollout(rollout.getId()), result -> success(result), 5000, 100)).isNotNull(); - + assertThat(doWithTimeout(() -> getRollout(rollout.getId()), result -> success(result), 60_000, 100)) + .isNotNull(); } @Test diff --git a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResourceTest.java b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResourceTest.java index fefe2a440..a85e25bed 100644 --- a/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResourceTest.java +++ b/hawkbit-rest-resource/src/test/java/org/eclipse/hawkbit/rest/resource/SoftwareModuleTypeResourceTest.java @@ -90,6 +90,46 @@ public class SoftwareModuleTypeResourceTest extends AbstractIntegrationTest { .andExpect(jsonPath("$total", equalTo(4))); } + @Test + @WithUser(principal = "uploadTester", allSpPermissions = true) + @Description("Checks the correct behaviour of /rest/v1/softwaremoduletypes GET requests with sorting by MAXASSIGNMENTS field.") + public void getSoftwareModuleTypesSortedByMaxAssignments() throws Exception { + SoftwareModuleType testType = softwareManagement + .createSoftwareModuleType(new SoftwareModuleType("test123", "TestName123", "Desc123", 5)); + testType.setDescription("Desc1234"); + testType = softwareManagement.updateSoftwareModuleType(testType); + + // descending + mvc.perform(get("/rest/v1/softwaremoduletypes").accept(MediaType.APPLICATION_JSON) + .param(RestConstants.REQUEST_PARAMETER_SORTING, "MAXASSIGNMENTS:DESC")) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$content.[0].id", equalTo(testType.getId().intValue()))) + .andExpect(jsonPath("$content.[0].name", equalTo("TestName123"))) + .andExpect(jsonPath("$content.[0].description", equalTo("Desc1234"))) + .andExpect(jsonPath("$content.[0].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[0].createdAt", equalTo(testType.getCreatedAt()))) + .andExpect(jsonPath("$content.[0].lastModifiedBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[0].lastModifiedAt", equalTo(testType.getLastModifiedAt()))) + .andExpect(jsonPath("$content.[0].maxAssignments", equalTo(5))) + .andExpect(jsonPath("$content.[0].key", equalTo("test123"))).andExpect(jsonPath("$total", equalTo(4))); + + // ascending + mvc.perform(get("/rest/v1/softwaremoduletypes").accept(MediaType.APPLICATION_JSON) + .param(RestConstants.REQUEST_PARAMETER_SORTING, "MAXASSIGNMENTS:ASC")) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(jsonPath("$content.[3].id", equalTo(testType.getId().intValue()))) + .andExpect(jsonPath("$content.[3].name", equalTo("TestName123"))) + .andExpect(jsonPath("$content.[3].description", equalTo("Desc1234"))) + .andExpect(jsonPath("$content.[3].createdBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[3].createdAt", equalTo(testType.getCreatedAt()))) + .andExpect(jsonPath("$content.[3].lastModifiedBy", equalTo("uploadTester"))) + .andExpect(jsonPath("$content.[3].lastModifiedAt", equalTo(testType.getLastModifiedAt()))) + .andExpect(jsonPath("$content.[3].maxAssignments", equalTo(5))) + .andExpect(jsonPath("$content.[3].key", equalTo("test123"))).andExpect(jsonPath("$total", equalTo(4))); + } + @Test @WithUser(principal = "uploadTester", allSpPermissions = true) @Description("Checks the correct behaviour of /rest/v1/softwaremoduletypes POST requests.") diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java index 2be62db1d..f4c26a960 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java @@ -61,7 +61,7 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { private static final String EMPTY_VIEW = ""; - private EventPushStrategy pushStrategy; + private transient EventPushStrategy pushStrategy; @Autowired private SpringViewProvider viewProvider; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java index b23935826..99ceb9aaf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/UiProperties.java @@ -44,16 +44,16 @@ public class UiProperties { /** * Demo tenant. */ - private String tenant = "DEFAULT"; + private String tenant = ""; /** * Demo user name. */ - private String user = "admin"; + private String user = ""; /** * Demo user password. */ - private String password = "admin"; + private String password = ""; public String getTenant() { return tenant; @@ -82,10 +82,13 @@ public class UiProperties { } /** - * Links to potentially other systems (e.g. support, user management etc.). + * Links to potentially other systems (e.g. support, user management, + * documentation etc.). * */ public static class Links { + private final Documentation documentation = new Documentation(); + /** * Link to product support. */ @@ -96,6 +99,121 @@ public class UiProperties { */ private String requestAccount = ""; + public Documentation getDocumentation() { + return documentation; + } + + /** + * Configuration of UI documentation links. + * + */ + public static class Documentation { + /** + * Link to root of documentation and user guides. + */ + private String root = ""; + + /** + * Link to documentation of deployment view. + */ + private String deploymentView = ""; + + /** + * Link to documentation of distribution view. + */ + private String distributionView = ""; + + /** + * Link to documentation of upload view. + */ + private String uploadView = ""; + + /** + * Link to documentation of system configuration view. + */ + private String systemConfigurationView = ""; + + /** + * Link to security related documentation. + */ + private String security = ""; + + /** + * Link to target filter view. + */ + private String targetfilterView = ""; + + /** + * Link to documentation of rollout view. + */ + private String rolloutView = ""; + + public String getDeploymentView() { + return deploymentView; + } + + public void setDeploymentView(final String deploymentView) { + this.deploymentView = deploymentView; + } + + public String getDistributionView() { + return distributionView; + } + + public void setDistributionView(final String distributionView) { + this.distributionView = distributionView; + } + + public String getUploadView() { + return uploadView; + } + + public void setUploadView(final String uploadView) { + this.uploadView = uploadView; + } + + public String getSystemConfigurationView() { + return systemConfigurationView; + } + + public void setSystemConfigurationView(final String systemConfigurationView) { + this.systemConfigurationView = systemConfigurationView; + } + + public String getSecurity() { + return security; + } + + public void setSecurity(final String security) { + this.security = security; + } + + public String getTargetfilterView() { + return targetfilterView; + } + + public void setTargetfilterView(final String targetfilterView) { + this.targetfilterView = targetfilterView; + } + + public String getRolloutView() { + return rolloutView; + } + + public void setRolloutView(final String rolloutView) { + this.rolloutView = rolloutView; + } + + public String getRoot() { + return root; + } + + public void setRoot(final String root) { + this.root = root; + } + + } + /** * Link to user management. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index 5b2e4ed9a..f5008eb31 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -47,10 +47,6 @@ import com.vaadin.ui.themes.ValoTheme; * Approach to create necessary UI component which are decorated Aspect of fine * tuning the component or extending the component is separated. * - * - * - * - * */ public final class SPUIComponentProvider { private static final Logger LOG = LoggerFactory.getLogger(SPUIComponentProvider.class); @@ -411,4 +407,22 @@ public final class SPUIComponentProvider { return link; } + + /** + * Generates help/documentation links from within management UI. + * + * @param uri + * to documentation site + * + * @return generated link + */ + public static Link getHelpLink(final String uri) { + + final Link link = new Link("", new ExternalResource(uri)); + link.setTargetName("_blank"); + link.setIcon(FontAwesome.QUESTION_CIRCLE); + link.setDescription("Documentation"); + return link; + + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/documentation/DocumentationPageLink.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/documentation/DocumentationPageLink.java deleted file mode 100644 index b4064ef68..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/documentation/DocumentationPageLink.java +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.documentation; - -import com.vaadin.server.ExternalResource; -import com.vaadin.server.FontAwesome; -import com.vaadin.ui.Link; - -/** - * enum declaration which contains all documentation links to the documenation - * which can be used to create the links to a specific documentation from a UI - * view. - * - * - * - * - */ -public enum DocumentationPageLink { - - // Root URL to index.html - ROOT_VIEW(""), - - // userguide/deployment - DEPLOYMENT_VIEW("deployment.html", DocumentationUtil.USERGUIDE), - - // userguide/distribution - DISTRIBUTION_VIEW("distribution.html", DocumentationUtil.USERGUIDE), - - // userguide/upload - UPLOAD_VIEW("upload.html", DocumentationUtil.USERGUIDE), - - // userguide/statistics - STATISTICS_VIEW("statistics.html", DocumentationUtil.USERGUIDE), - - // userguide - SYSTEM_CONFIGURATION_VIEW("systemconfiguration.html", DocumentationUtil.USERGUIDE), - - // authentication/security - TARGET_SECURITY_TOKEN("security.html", DocumentationUtil.DEVELOPERGUIDE, "concepts"), - - // userguide/targetfilter - TARGET_FILTER_VIEW("targetfilter.html", DocumentationUtil.USERGUIDE), - - // userguide/ROLLOUT - ROLLOUT_VIEW("rollout.html", DocumentationUtil.USERGUIDE); - - private static final String ROOT_PATH = "../documentation"; - - private final String[] path; - private final String page; - - private DocumentationPageLink(final String page, final String... path) { - this.path = path; - this.page = page; - } - - public String getPath() { - final StringBuilder builder = new StringBuilder(ROOT_PATH); - for (final String string : path) { - builder.append('/').append(string); - } - return builder.append('/').append(page).toString(); - } - - public Link getLink() { - final Link link = new Link("", new ExternalResource(getPath())); - link.setTargetName("_blank"); - link.setIcon(FontAwesome.QUESTION_CIRCLE); - link.setDescription("Documentation"); - return link; - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/documentation/DocumentationUtil.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/documentation/DocumentationUtil.java deleted file mode 100644 index 2454f1903..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/documentation/DocumentationUtil.java +++ /dev/null @@ -1,47 +0,0 @@ -/** - * Copyright (c) 2015 Bosch Software Innovations GmbH and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - */ -package org.eclipse.hawkbit.ui.documentation; - -/** - * Constants for documentation navigation. - * - * - * - */ -public final class DocumentationUtil { - - /** - * Navigation string to introduction folder. - */ - public static final String INTRODUCTION = "introduction"; - - /** - * Navigation string to userguide folder. - */ - public static final String USERGUIDE = "userguide"; - - /** - * Navigation string to developerguide folder. - */ - public static final String DEVELOPERGUIDE = "developerguide"; - - /** - * Navigation string to releasenotes folder. - */ - public static final String RELEASENOTES = "releasenotes"; - - /** - * Navigation string to glossary folder. - */ - public static final String GLOSSARY = "glossary"; - - private DocumentationUtil() { - } - -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java index 43f5919ef..6c0324a6a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java @@ -16,10 +16,10 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetFilterQueryManagement; import org.eclipse.hawkbit.repository.model.TargetFilterQuery; +import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIButton; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.filtermanagement.event.CustomFilterUIEvent; import org.eclipse.hawkbit.ui.filtermanagement.state.FilterManagementUIState; import org.eclipse.hawkbit.ui.utils.I18N; @@ -86,6 +86,9 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button @Autowired private UINotification notification; + @Autowired + private transient UiProperties uiProperties; + @Autowired @Qualifier("uiExecutor") private transient Executor executor; @@ -212,7 +215,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button validationIcon = createStatusIcon(); saveButton = createSaveButton(); - helpLink = DocumentationPageLink.TARGET_FILTER_VIEW.getLink(); + helpLink = SPUIComponentProvider.getHelpLink(uiProperties.getLinks().getDocumentation().getTargetfilterView()); closeIcon = createSearchResetIcon(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/login/LoginView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/login/LoginView.java index 484333219..0ddf0fcd3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/login/LoginView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/login/LoginView.java @@ -17,7 +17,6 @@ import org.eclipse.hawkbit.im.authentication.MultitenancyIndicator; import org.eclipse.hawkbit.im.authentication.TenantUserPasswordAuthenticationToken; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; import org.slf4j.Logger; @@ -53,9 +52,6 @@ import com.vaadin.ui.themes.ValoTheme; /** * Login view for login credentials. - * - * - * */ @SpringView(name = "") @UIScope @@ -228,16 +224,20 @@ public class LoginView extends VerticalLayout implements View { links.addStyleName("links"); final String linkStyle = "v-link"; - final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENATION, - i18n.get("link.documentation.name"), "../" + DocumentationPageLink.ROOT_VIEW.getPath(), - FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true); - links.addComponent(docuLink); - docuLink.addStyleName(ValoTheme.LINK_SMALL); + if (!uiProperties.getLinks().getDocumentation().getRoot().isEmpty()) { + final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENATION, + i18n.get("link.documentation.name"), uiProperties.getLinks().getDocumentation().getRoot(), + FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true); + links.addComponent(docuLink); + docuLink.addStyleName(ValoTheme.LINK_SMALL); + } - final Link demoLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DEMO, - i18n.get("link.demo.name"), "?demo", FontAwesome.DESKTOP, "_top", linkStyle, true); - links.addComponent(demoLink); - demoLink.addStyleName(ValoTheme.LINK_SMALL); + if (!uiProperties.getDemo().getUser().isEmpty()) { + final Link demoLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DEMO, + i18n.get("link.demo.name"), "?demo", FontAwesome.DESKTOP, "_top", linkStyle, true); + links.addComponent(demoLink); + demoLink.addStyleName(ValoTheme.LINK_SMALL); + } if (!uiProperties.getLinks().getRequestAccount().isEmpty()) { final Link requestAccountLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_REQUESTACCOUNT, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java index 44634618e..3f7b7eee5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/actionhistory/ActionHistoryTable.java @@ -844,7 +844,7 @@ public class ActionHistoryTable extends TreeTable implements Handler { if (actionId != null) { final Action activeAction = deploymentManagement.findAction(actionId); try { - deploymentManagement.forceQuitAction(activeAction, target); + deploymentManagement.forceQuitAction(activeAction); return true; } catch (final CancelActionNotAllowedException e) { LOG.info("Force Cancel action not allowed exception :{}", e); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index 72174a0c5..657cd97af 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -18,9 +18,9 @@ import javax.annotation.PreDestroy; import org.eclipse.hawkbit.repository.DeploymentManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.DistributionSetIdName; +import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.management.dstable.DistributionBeanQuery; import org.eclipse.hawkbit.ui.management.event.BulkUploadPopupEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; @@ -88,6 +88,9 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { @Autowired private transient DeploymentManagement deploymentManagement; + @Autowired + private transient UiProperties uiproperties; + private static final long serialVersionUID = -6659290471705262389L; private VerticalLayout tokenVerticalLayout; private TextArea descTextArea; @@ -141,7 +144,8 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { progressBar = creatreProgressBar(); targetsCountLabel = getStatusCountLabel(); bulkUploader = getBulkUploadHandler(); - linkToSystemConfigHelp = DocumentationPageLink.DEPLOYMENT_VIEW.getLink(); + linkToSystemConfigHelp = SPUIComponentProvider + .getHelpLink(uiproperties.getLinks().getDocumentation().getDeploymentView()); windowCaption = new Label(i18n.get("caption.bulk.upload.targets")); minimizeButton = getMinimizeButton(); closeButton = getCloseButton(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java index beff0e6b9..bbbba8cec 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java @@ -23,7 +23,6 @@ import org.eclipse.hawkbit.im.authentication.PermissionService; import org.eclipse.hawkbit.im.authentication.UserPrincipal; import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; @@ -151,13 +150,15 @@ public final class DashboardMenu extends CustomComponent { links.addStyleName("links"); final String linkStyle = "v-link"; - final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENATION, - i18n.get("link.documentation.name"), "../" + DocumentationPageLink.ROOT_VIEW.getPath(), - FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true); - docuLink.setDescription(i18n.get("link.documentation.name")); - docuLink.setSizeFull(); - links.addComponent(docuLink); - links.setComponentAlignment(docuLink, Alignment.BOTTOM_CENTER); + if (!uiProperties.getLinks().getDocumentation().getRoot().isEmpty()) { + final Link docuLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_DOCUMENATION, + i18n.get("link.documentation.name"), uiProperties.getLinks().getDocumentation().getRoot(), + FontAwesome.QUESTION_CIRCLE, "_blank", linkStyle, true); + docuLink.setDescription(i18n.get("link.documentation.name")); + docuLink.setSizeFull(); + links.addComponent(docuLink); + links.setComponentAlignment(docuLink, Alignment.BOTTOM_CENTER); + } if (!uiProperties.getLinks().getUserManagement().isEmpty()) { final Link userManagementLink = SPUIComponentProvider.getLink(SPUIComponetIdProvider.LINK_USERMANAGEMENT, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 29aa182e5..e5e86c520 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -26,9 +26,9 @@ import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorAction import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition; import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessAction; import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition; +import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.filtermanagement.TargetFilterBeanQuery; import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout; import org.eclipse.hawkbit.ui.management.footer.ActionTypeOptionGroupLayout.ActionTypeOption; @@ -104,6 +104,9 @@ public class AddUpdateRolloutWindowLayout extends CustomComponent { @Autowired private UINotification uiNotification; + @Autowired + private transient UiProperties uiProperties; + @Autowired private I18N i18n; @@ -284,7 +287,7 @@ public class AddUpdateRolloutWindowLayout extends CustomComponent { totalTargetsLabel = createTotalTargetsLabel(); targetFilterQuery = createTargetFilterQuery(); - linkToHelp = DocumentationPageLink.ROLLOUT_VIEW.getLink(); + linkToHelp = SPUIComponentProvider.getHelpLink(uiProperties.getLinks().getDocumentation().getRolloutView()); actionTypeOptionGroupLayout.addStyleName(SPUIStyleDefinitions.ROLLOUT_ACTION_TYPE_LAYOUT); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java index dc44e6de8..7cf69f460 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/TenantConfigurationDashboardView.java @@ -9,9 +9,9 @@ package org.eclipse.hawkbit.ui.tenantconfiguration; import org.eclipse.hawkbit.ui.HawkbitUI; +import org.eclipse.hawkbit.ui.UiProperties; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.documentation.DocumentationPageLink; import org.eclipse.hawkbit.ui.tenantconfiguration.ConfigurationGroup.ConfigurationGroupChangeListener; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider; @@ -54,6 +54,9 @@ public class TenantConfigurationDashboardView extends CustomComponent @Autowired private I18N i18n; + @Autowired + private transient UiProperties uiProperties; + @Autowired private transient UINotification uINotification; @@ -101,7 +104,9 @@ public class TenantConfigurationDashboardView extends CustomComponent undoConfigurationBtn.addClickListener(event -> undoConfiguration()); hlayout.addComponent(undoConfigurationBtn); - final Link linkToSystemConfigHelp = DocumentationPageLink.SYSTEM_CONFIGURATION_VIEW.getLink(); + final Link linkToSystemConfigHelp = SPUIComponentProvider + .getHelpLink(uiProperties.getLinks().getDocumentation().getSystemConfigurationView()); + ; hlayout.addComponent(linkToSystemConfigHelp); return hlayout;